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

来源:互联网 发布:网络剧受众画像 编辑:程序博客网 时间:2024/04/27 17:57

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

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

这个时候用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次的效果分别如下:

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

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

效果如下,挺好的。



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

void thin(IplImage *hsv, IplImage *&pDst){IplImage *pTemp = cvCreateImage(cvGetSize(hsv), hsv->depth, 1);  if (hsv->nChannels == 3)cvCvtColor(hsv, pTemp, CV_BGR2GRAY);elsecvCopy(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);






0 0