Search code examples
c++opencvros

Absdiff in openCV can compile but show black image


I have been trying to use absdiff to find the motion in an image,but unfortunately it fail,i am new to OpenCV. The coding supposed to use absdiff to determine whether any motion is happening around or not, but the output is a pitch black for diff1,diff2 and motion. Meanwhile,next_mframe,current_mframe, prev_mframe shows grayscale images. While, result shows a clear and normal image. I use this as my reference http://manmade2.com/simple-home-surveillance-with-opencv-c-and-raspberry-pi/. I think the all the image memory is loaded with the same frame and compare, that explain why its a pitch black. Is there any others method i miss there? I am using RTSP to pass camera RAW image to ROS.

    void imageCallback(const sensor_msgs::ImageConstPtr&msg_ptr){

    CvPoint center;
    int radius, posX, posY;

    cv_bridge::CvImagePtr cv_image;     //To parse image_raw from rstp
    try
    {
        cv_image = cv_bridge::toCvCopy(msg_ptr, enc::BGR8);
    }
    catch (cv_bridge::Exception& e)
    {
      ROS_ERROR("cv_bridge exception: %s", e.what());
      return;
    }

    frame = new IplImage(cv_image->image);    //frame now holding raw_image
    frame1 = new IplImage(cv_image->image); 
    frame2 = new IplImage(cv_image->image); 
    frame3 = new IplImage(cv_image->image); 

     matriximage = cvarrToMat(frame);
     cvtColor(matriximage,matriximage,CV_RGB2GRAY);  //grayscale

     prev_mframe = cvarrToMat(frame1);
     cvtColor(prev_mframe,prev_mframe,CV_RGB2GRAY);  //grayscale
     current_mframe = cvarrToMat(frame2);
     cvtColor(current_mframe,current_mframe,CV_RGB2GRAY);  //grayscale
     next_mframe = cvarrToMat(frame3);
     cvtColor(next_mframe,next_mframe,CV_RGB2GRAY);  //grayscale

     // Maximum deviation of the image, the higher the value, the more motion is allowed
    int max_deviation = 20;

    result=matriximage;

    //rellocate image in right order
    prev_mframe = current_mframe;
    current_mframe = next_mframe;
    next_mframe = matriximage;
    //motion=difflmg(prev_mframe,current_mframe,next_mframe);

    absdiff(prev_mframe,next_mframe,diff1); //Here should show black and white image
    absdiff(next_mframe,current_mframe,diff2);
    bitwise_and(diff1,diff2,motion);
    threshold(motion,motion,35,255,CV_THRESH_BINARY);
    erode(motion,motion,kernel_ero);


    imshow("Motion Detection",result);
    imshow("diff1",diff1);  //I tried to output the image but its all black
    imshow("diff2",diff2);  //same here, I tried to output the image but its all black
    imshow("diff1",motion);
    imshow("nextframe",next_mframe);
    imshow("motion",motion);

    char c =cvWaitKey(3);  }

Solution

  • I change the cv_bridge method to VideoCap, its seem to functions well, cv_bridge just cannot save the image even through i change the IplImage to Mat format. Maybe there is other ways, but as for now, i will go with this method fist.

    VideoCapture cap(0); 
    Tracker(void)
    {
        //check if camera worked
        if(!cap.isOpened())
        {
            cout<<"cannot open the Video cam"<<endl;
        }
        cout<<"camera is opening"<<endl;
    
        cap>>prev_mframe;
        cvtColor(prev_mframe,prev_mframe,CV_RGB2GRAY);  // capture 3 frame and convert to grayscale
        cap>>current_mframe;
        cvtColor(current_mframe,current_mframe,CV_RGB2GRAY);  
        cap>>next_mframe;
        cvtColor(next_mframe,next_mframe,CV_RGB2GRAY); 
    
        //rellocate image in right order
        current_mframe.copyTo(prev_mframe);
        next_mframe.copyTo(current_mframe);
        matriximage.copyTo(next_mframe);
    
        motion = diffImg(prev_mframe, current_mframe, next_mframe);
    }