収縮・膨張で砂嵐ノイズフィルタ
cvErode()とcvDilate()を使うと砂嵐ノイズを消せる。効果はそれぞれ収縮と膨張で、収縮→膨張とすると小さなゴミは消えるし、膨張→収縮でひびわれは押し潰される。
いや2回やらなくても良い気もしてきた。
こうなる
こういうas3のColorMatrixFilterみたいな処理はOpenCV爆速みたい
途中の膨張・収縮のコメントアウトを外すとノイズを飛ばせる。第3引数NULLだと3x3のmatrixで変形されるらしい。第4引数は膨張・収縮回数。
bgsub.cpp 背景差分 - 橋本詳解を少し修正した
#include <stdio.h> #include <highgui.h> #include <cv.h> int main(int argc, char** argv) { bool isStop = false; CvCapture *capture = NULL; capture = cvCreateCameraCapture(0); //capture = cvCaptureFromAVI("test.avi"); if(capture == NULL){ printf("capture device not found!!"); return -1; } IplImage *img = NULL; img = cvQueryFrame(capture); const int w = img->width; const int h = img->height; IplImage *imgBg = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1); IplImage *imgGray = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1); IplImage *imgDiff = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1); char winNameCapture[] = "Capture"; char winNameDiff[] = "Difference"; char winNameBg[] = "Background"; cvNamedWindow(winNameCapture, CV_WINDOW_AUTOSIZE); cvNamedWindow(winNameDiff, CV_WINDOW_AUTOSIZE); cvNamedWindow(winNameBg, CV_WINDOW_AUTOSIZE); img = cvQueryFrame(capture); cvCvtColor(img, imgBg, CV_BGR2GRAY); int waitKey; while (1) { if(!isStop){ if((img = cvQueryFrame(capture)) == NULL) break; cvCvtColor(img, imgGray,CV_BGR2GRAY); cvAbsDiff(imgGray, imgBg, imgDiff); cvThreshold(imgDiff, imgDiff, 10, 255, CV_THRESH_BINARY); // cvErode(imgDiff, imgDiff, NULL, 1); // 収縮 // cvDilate(imgDiff, imgDiff, NULL, 2); // 膨張 // cvErode(imgDiff, imgDiff, NULL, 1); // 収縮 cvShowImage(winNameCapture, img); cvShowImage(winNameDiff, imgDiff); cvShowImage(winNameBg, imgBg); } waitKey = cvWaitKey(33); if(waitKey == 'q') break; if(waitKey == 'b'){ // 背景再取得 img = cvQueryFrame(capture); cvCvtColor(img, imgBg, CV_BGR2GRAY); } if(waitKey == ' '){ isStop = !isStop; if(isStop) printf("stop\n"); else printf("start\n"); } } cvReleaseCapture(&capture); cvDestroyWindow(winNameCapture); cvDestroyWindow(winNameDiff); cvDestroyWindow(winNameBg); return 0; }