収縮・膨張で砂嵐ノイズフィルタ

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;
}