2017-06-22 10 views
1

私はabsdiffを使用してイメージの動きを見つけようとしていますが、残念ながら失敗しました。 absdiffを使用して動きが発生しているかどうかを判断するコードは、diff1diff2およびmotionのピッチ・ブラックです。一方、next_mframe,current_mframe,prev_mframeはグレースケール画像を示す。一方、resultは、明確で正常な画像を示しています。私は参考としてこれを使用しますhttp://manmade2.com/simple-home-surveillance-with-opencv-c-and-raspberry-pi/。私はすべての画像のメモリが同じフレームで読み込まれ、比較すると、それはなぜそのピッチ黒を説明すると思います。他の方法がありますか?私はRTSPを使ってカメラを渡していますRAWイメージをROSに転送しています。OpenCVのAbsdiffはコンパイルできますが、黒い画像が表示されます

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); } 
+1

1. IplImage apiを使用しないでください。古いです。代わりにcv :: Matを使用してください! 2.あなたの 'frame3 = new IplImage(cv_image-> image);'はデータをコピーするのではなく、同じメモリを使用すると思います。代わりにディープコピーメソッドが必要になります。これは、自分自身から同じイメージを減算するだけで、あなたのadsDiffがどこでも0である理由を説明します。 – Micka

+0

ありがとう、私はCopyTo()とクローン()関数は、この問題を解決するのに役立つことができるディープコピーメソッドを使用する場合は、意味ですか?私は、関数cv_bridgeを使って生のイメージをサブブロックするためにROSを使用していますが、Raw Imageのサポートもしていますか?またはIplImageからMatへの変換が必要ですか? – Sky

+0

割り当ての代わりに、すべてのcvArrToMat行と "正しい順序でイメージを再配置する"部分でも、複製またはコピーを試みてください。しかし、あなたのサンプルコードでは、frame、frame1、frame2、およびframe3は、同じ画像情報を保持します。異なる画像をロード/使用しよう!初期化コードを実行しようとしているだけで、新しいイメージをロードしてprev/current/nextフレームを繰り返し更新するループがない可能性がありますか? – Micka

答えて

0

私はそのcv_bridgeはちょうど私がマット形式にIplImageへの変更にも介して画像を保存することはできません、うまく機能しているように見える、VideoCapにcv_bridge方法を変更します。他の方法があるかもしれないが、今のところ、私はこの方法の拳で行くだろう。

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); 
} 
関連する問題