项目需要看了种子填充算法,改进了算法主要去除面积小的部分。种子填充算法分为两种,简单的和基于扫描线的方法,简单的算法如下描述(笔者针对的是二值图像):
(1)从上到下,从左到有,依次扫描每个像素;
(2)遇到一个非零数值压栈,并置原图像像素点值为0,面积初始化为1;否则,处理完毕。
(3)对栈非空查找,如果非空弹出栈顶,检测4领域或8领域,如果非空压栈,并置原图像像素点为0,标示不在处理此点,面积加1;如果为空,停止;
(4)判断面积是否大于给定阈值,小于的删掉,大于的把得到的所有像素点保存到目标图像上去,继续扫描像素,转2。
这里我用c++实现,开始用的stl栈,运行一段时间会有中断,之后换成链表可以了,代码共享如下,可以运行,图片使用二值,有需要的可以留下邮箱,一起研究:
1 //视频处理测试算法,种子填充算法,扫描线算法,二值图像 2 //用栈会保存,这里把栈换成链表了,下面有栈注释掉代码 3 //20140911 4 #include <iostream> 5 #include "cv.h" 6 #include "highgui.h" 7 #include <stack> 8 #include <list> 9 #include <string> 10 11 using namespace std; 12 int ScanLine_SeedFillingAlgo(IplImage *src,IplImage *dst,int MinCutNumb);//原图像和目标图像不要是同一副图像 13 int main() 14 { 15 IplImage *ipl_origin; 16 IplImage *ipl_target; 17 string fname = "D:/无腐蚀膨胀/Fight1save"; 18 cvNamedWindow("原始图片"); 19 cvNamedWindow("处理后图片"); 20 for (int k=0;k<110;k++) 21 { 22 string filename=""; 23 char tmp[20]; 24 _itoa_s(k,tmp,20,10); 25 filename+=tmp; 26 filename+=".bmp"; 27 filename=fname+filename; 28 ipl_origin=cvLoadImage(filename.c_str(),-1); 29 ipl_target=cvCreateImage(cvGetSize(ipl_origin),8,1);//cvCloneImage(ipl_origin); 30 31 cvZero(ipl_target); 32 cvShowImage("原始图片",ipl_origin); 33 int s=clock(); 34 ScanLine_SeedFillingAlgo(ipl_origin,ipl_target,125); 35 int e=clock(); 36 std::cout<<"\n"<<e-s; 37 cvShowImage("处理后图片",ipl_target); 38 cvWaitKey(1); 39 cvReleaseImage(&ipl_origin); 40 cvReleaseImage(&ipl_target); 41 } 42 43 44 cvWaitKey(0); 45 46 cvDestroyWindow("原始图片"); 47 cvDestroyWindow("处理后图片"); 48 49 } 50 //MinCutNumb代表剔除面积小于MinCutNumb的值; 51 //返回找到目标数 |