图片中线条的细化处理实验

之前对标尺图片进行了颜色滤波,使得图像中只剩下了红色的刻度,那么接下来希望找到这些刻度,并得到它们之间的距离作为一个度量标准。

不过问题来了,经过滤波处理后得到的刻度并不是一条直线,看上去是一个矩形框框,如图

图片中线条的细化处理实验_第1张图片

这个时候用cvHoughLines2来找直线效果可就很不好哦,因为都是矩形框框。

想到图形学课上说过有腐蚀Erode这个操作,所以试了一试:

opencv中的腐蚀函数为:

第三个参数为采用的模板,默认取0,则为3*3模板,最后一个参数为腐蚀的迭代次数,如果腐蚀效果不明显,可以增加腐蚀次数。

CVAPI(void)  cvErode( const CvArr* src, CvArr* dst,
                      IplConvKernel* element CV_DEFAULT(NULL),
                      int iterations CV_DEFAULT(1) );
void Erode(IplImage *img)
{
    <span style="white-space:pre">	</span>cvNamedWindow("Eroded image", CV_WINDOW_AUTOSIZE);
	//对彩色图像进行处理
	if (!img)
	{
		cerr << "The input image is not valid\n";
		return ;
	}
	if (img->nChannels != 3)
	{
		cerr << "The input image is not a color image\n";
		return ;
	}
	IplImage* erodedImage=cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
   <span style="white-space:pre">	</span>cvErode(img, erodedImage, 0, 2);//腐蚀
    <span style="white-space:pre">	</span>cvShowImage("Eroded image", erodedImage);
  <span style="white-space:pre">	</span>cvWaitKey(0);//暂停用于显示图片
<span style="white-space:pre">	</span>cvDestroyWindow("Eroded image");
}
腐蚀1次,2次,3次的效果分别如下:

图片中线条的细化处理实验_第2张图片图片中线条的细化处理实验_第3张图片

1次和2次腐蚀效果都不算特别好,三次腐蚀倒是变成一条线了,可是却有一些刻度不见了。所以腐蚀不是很满足我的要求。

接下来考虑图像的细化算法,具体采用的是qianchenglenger的专栏所实现的方法。

效果如下,挺好的。

图片中线条的细化处理实验_第4张图片

关于那个细化方法的调用,我也写了点代码,它的方法使用前要对图片做些预处理

void thin(IplImage *hsv, IplImage *&pDst)
{

	IplImage *pTemp = cvCreateImage(cvGetSize(hsv), hsv->depth, 1);  
	if (hsv->nChannels == 3)
		cvCvtColor(hsv, pTemp, CV_BGR2GRAY);
	else
		cvCopy(hsv, pTemp);
	//如果pDst不为空,则先释放掉它再重新申请空间
	if (pDst)
		cvReleaseImage(&pDst);
	pDst = cvCreateImage(cvGetSize(hsv), hsv->depth, 1);  
      
    //将原图像转换为二值图像  
	/*
		void cvThreshold
		(	const CvArr* src,
			CvArr* dst,
			double threshold,
			double max_value,
			int threshold_type );
		第三个参数是阈值
		当threshold_type = CV_THRESH_BINARY的时候
		对于src中的任一(x,y)处的像素,
		if src(x,y) > threshold
		  dst(x,y) = max_value;
		所以下面的二值化是将所有大于阈值的点像素值都设置为1。
		为什么要设置成1呢?这个是细化算法规定的啦。
		原实例代码中的阈值设的是128,太高了,因为我首先已经做过滤波,所以将阈值设为1。
	*/
    cvThreshold(pTemp,pTemp,1,1,CV_THRESH_BINARY);   
    //图像细化  
    thinImage(pTemp,pDst);  
	//图像细化处理之后pDst中每个像素值要么为0,要么为1,所以下面需要把1变为255,这样看起来才明显对吧
	for (int i=0; i<pDst->height; ++i)  
    {  
        for (int j=0; j<pDst->width; ++j)  
        {  
            if(CV_IMAGE_ELEM(pDst,uchar,i,j)==1)  
                CV_IMAGE_ELEM(pDst,uchar,i,j)= 255;  
        }  
    }  
	
}
我这个函数这样调用就可以啦

<span style="white-space:pre">	</span>IplImage *pDst = NULL;
	thin(hsv, pDst);






你可能感兴趣的:(图片,opencv,图形,细化,图像处理)