使用openCV去除二值图像中的噪声
Posted
技术标签:
【中文标题】使用openCV去除二值图像中的噪声【英文标题】:removing noise in a binary image using openCV 【发布时间】:2012-03-08 13:34:26 【问题描述】:我使用 openCV 将视频读入 Visual Studio 并将其转换为灰度,然后使用函数 CV_THRESH_BINARY 将其转换为二进制图像。但是,框架中存在孔洞和噪音。什么是消除噪音或孔洞的简单方法?我已经阅读了 openCV 中的 Erode 和 Dilate 函数,但我不太清楚如何使用它们。到目前为止,这是我的代码。如果有人能告诉我如何在我的代码中加入噪声消除,将不胜感激。
#include "cv.h"
#include "highgui.h"
int main( int argc, char* argv )
CvCapture *capture = NULL;
capture = cvCaptureFromAVI("C:\\walking\\lady walking.avi");
if(!capture)
return -1;
IplImage* color_frame = NULL;
IplImage* gray_frame = NULL ;
int thresh_frame = 70;
int frameCount=0;//Counts every 5 frames
cvNamedWindow( "Binary video", CV_WINDOW_AUTOSIZE );
while(1)
color_frame = cvQueryFrame( capture );//Grabs the frame from a file
if( !color_frame ) break;
gray_frame = cvCreateImage(cvSize(color_frame->width, color_frame->height), color_frame->depth, 1);
if( !color_frame ) break;// If the frame does not exist, quit the loop
frameCount++;
if(frameCount==5)
cvCvtColor(color_frame, gray_frame, CV_BGR2GRAY);
cvThreshold(gray_frame, gray_frame, thresh_frame, 255, CV_THRESH_BINARY);
cvShowImage("Binary video", gray_frame);
frameCount=0;
char c = cvWaitKey(33);
if( c == 27 ) break;
cvReleaseImage(&color_frame);
cvReleaseImage(&gray_frame);
cvReleaseCapture( &capture );
cvDestroyWindow( "Grayscale video" );
return 0;
【问题讨论】:
【参考方案1】:免责声明:很难给出一个好的答案,因为您提供的信息很少。如果您在二值化之前和之后发布图像,那会容易得多。不过,我会尽量给出一些提示。
如果孔比较大,那么可能是阈值错误,尝试增加或减少它并检查结果。你可以试试
cv::threshold(gray_frame, gray_frame, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
这将自动计算阈值。 如果找不到合适的阈值,那就试试一些自适应阈值算法,opencv有adaptiveThreshold()函数,但不是那么好。
如果孔洞和噪点非常小(每个只有几个像素),您可以尝试以下方法:
使用开(腐蚀,下一个膨胀)去除白噪声,用闭(膨胀,下一个腐蚀)去除小黑噪声。但请记住,该开口在消除白噪声的同时也会增强黑噪声,反之亦然。
进行阈值处理后的中值模糊。它可以去除黑色和白色的小噪声,同时保留颜色(图像仍然是二进制的),并且可能存在小错误,形状。在二值化之前应用中值模糊也可能有助于减少小噪声。
【讨论】:
很抱歉没有提供图片,但非常感谢您的帮助。我使用了 cvErode 函数,它消除了图像中的一些洞,但我也会尝试中值模糊。当您提到使用打开和关闭时,我必须同时使用它们还是使用 CV_MOP_OPEN 或 CV_MOP_CLOSE? 您仍然可以提供它们 :) 您可以使用其中一个或两个,一个接一个,这取决于您要实现的目标。只需检查结果和实验即可。 我检查了结果并确定使用 Erode 和 Dilate 函数可以获得更好的结果,所以我将一个接一个地使用它们。无论如何,我不知道如何提供图像,因为我是 *** 的新手:/ 非常抱歉。我目前正在从事一个涉及 C++ 和 openCV 的图像处理项目。它基于动作识别,所以如果我发布更多问题,如果你能提供一些帮助,我将不胜感激,因为你已经非常有帮助了。谢谢:) 您能否对我的问题进行投票,以便我获得超过 10 的声望?我想为这个问题发布图片***.com/questions/9372687/… 但这需要超过 10 个代表,这是我目前所处的位置。如果您也可以就这个问题提供一些帮助,那就太好了:)【参考方案2】:在进行阈值处理之前,您可以尝试使用 Smooth 函数和 CV_MEDIAN
。
【讨论】:
这会达到与腐蚀和扩张功能相同的结果吗?你熟悉这些功能的使用吗? 你可以使用开闭(腐蚀+膨胀,反之亦然),显然你需要调整内核大小 我可以使用打开或关闭功能还是必须一起使用它们? @user1204698,不,它与 erode 和 dilate 函数不同 - 这是您可以在阈值处理之前应用的另一种降低噪声的方法。侵蚀和扩张将是互补的,如果效果最好的话,你没有理由不能组合这些方法。 @MarkRansom 非常感谢您的帮助。我同时尝试了侵蚀和扩张,得到了更好的结果,所以我可能会坚持这种方法。以上是关于使用openCV去除二值图像中的噪声的主要内容,如果未能解决你的问题,请参考以下文章