OpenCVを使って画像のノイズ除去を考えています
OpenCVを使って画像のノイズ除去を考えています。
ですが、プログラムで上手く動いてくれないところがあり、分からなくて困っています。
もしわかる方がいらっしゃれば是非教えてください。
OpenCV2.4.6,VisualC++2010を用いています。
OpenCVを使わないLabeling.hなどを使った似たようなプログラムを教えてくださっても構いません。
ただ、Labeling.h自体がよくわからなく、Labeling.hを使って書いたプログラムが動かない状態であり、OpenCVの方がまだわかるので今回はOpenCVで質問しました。
プログラム(OpenCVを使った)の詳しい説明です。
入力画像の黒い点すべてがノイズだとします。またノイズのサイズは500以下だとします。
またサイズは特に指定はありません。拡張子は24bitのbmpを使っています。
画像の左側が入力画像とした時、画像の右側のように出力されます。(画像では分かりやすいように画像の切れ目を青の枠で囲っています。)
出力画像のふち?の部分が1ピクセルの範囲だけノイズ除去されずに残ってしまいます。(画像では分かりずらいですが赤の矢印の先の部分です。)
画像の下側のように赤のふち?1ピクセルの範囲はノイズ除去されません。
原因を考えているのですが、自分では分からなく困っています。
もしわかる方がいらっしゃれば是非教えてください。
私自身、プログラムは大学の授業レベル、OpenCVは使い始めて数ヶ月なので詳しくないです。
よろしくお願いします。
プログラムの内容は以下のようになっています。
〇〇〇は入力画像のファイル指定先
●●●は出力画像のファイル指定先
ノイズのサイズは500以下とします。
自分は輪郭追跡のcvPointの部分が怪しいと考えてます。
今書いてるプログラムから一部抜き出してきたのでもしかしたら余計な処理が入っているかもしれません。
一応コピペでライブラリの設定、入力・出力画像のファイル指定をしていただくと動くと思います。
#include "stdafx.h"
#include <stdio.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"
int _tmain(int argc, _TCHAR* argv[])
{
IplImage *Proc;//処理画像
int i;
char input_fname[256]; //元画像読み込み先
char output_fname[256]; //処理後画像出力先
//輪郭情報
CvMemStorage* Storage;//メモリストレージ
CvSeq* Contours=0;//輪郭データ
int Count=0;//輪郭の数
double Area=0;//面積
Storage=cvCreateMemStorage(0);//メモリストレージを確保
sprintf(input_fname, "〇〇〇");
sprintf(output_fname, "●●●");
IplImage *Input = cvLoadImage( input_fname, CV_LOAD_IMAGE_GRAYSCALE);
if( Input == NULL ){
printf("ファイルが読み込めません。\n");
cvWaitKey(0); // キー入力待機
return -1;
}
// (1)二値化(大津の手法を利用)
cvThreshold (Input, Input, 0, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);//大津の二値化を用いて色を反転させる
Proc = cvCreateImage(cvGetSize(Input), Input->depth, 1);//処理画像
cvCopy(Input,Proc,NULL);
//輪郭を取得
Count = cvFindContours(Proc,Storage,&Contours,sizeof(CvContour),CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));
//輪郭情報の取得
for(i=1;i<=Count;i++){
Area=abs(cvContourArea(Contours));//面積
if(Area<500){//面積が500以下の場合、黒で塗りつぶす
cvDrawContours( Input, Contours, CV_RGB(0,0,0),CV_RGB(0,0,0), 0, CV_FILLED);}
Contours=Contours->h_next;//次の輪郭へ
}
cvThreshold (Input, Input, 0, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);//大津の二値化を用いて色を反転させる
cvSaveImage(output_fname,Input);//矩形描画した画像を保存
//画像情報解放
cvReleaseImage(&Input);
cvReleaseImage(&Proc);
}
お礼
返信遅くなりすいません お使いのopencvのバージョン2.2.0でしょうか? そのせいかとも思っていますが,今は環境を変えたくないので確認できていません。 vector<Point> approx; contourArea(Mat(approx) で代用してとりあえず動いていますので, もう少したってバージョンupして確認してみます。 ありがとうございました。
補足
回答ありがとうございます。 ソース全体は次のとおりです。 宜しくお願いします #include "stdafx.h" #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using namespace std; int _tmain(int argc, _TCHAR* argv[]) { vector<Point> contour; contour.push_back(Point2f(0, 0)); contour.push_back(Point2f(10, 0)); contour.push_back(Point2f(10, 10)); contour.push_back(Point2f(5, 4)); double area0 = contourArea(contour); vector<Point> approx; approxPolyDP(contour, approx, 5, true); double area1 = contourArea(approx); cout << "area0 =" << area0 << endl << "area1 =" << area1 << endl << "approx poly vertices" << approx.size() << endl; return 0;