基于OpenCV的图像测量

在工业检测领域,经常会遇到用计算机去检测感兴趣图像(ROI区域)的一些图像特性,例如目标物体的面积,目标物体的长度和宽度,以此判断产品合不合格。例如在自动化流水线上,经常需要看工人们或者机器手有没有把焊锡焊好,卡口有没有卡紧等。这些用人工固然可以,现代大多数车间都是用机器视觉系统代替人眼去检测的。这有很多优点,机器能在环境恶劣的条件下,长时间,精准的,快速的工作,这是人所做不到的。

例如下面如要计算机检测工件有没有焊好,就需要用到模式识别、机器视觉方面的知识,这里我使用OpenCV 2.1版本。图像测量是机器视觉最为基础和简单的方法。


基于OpenCV的图像测量_第1张图片


要检测途中的引线有没有焊上,我的算法的核心是先提取出目标区域,再测量引线在引脚上的宽度,是不是宽窄不一。若有宽度不一,且宽度差距较大,则说明已经焊上。

如果哪位朋友有更好的方法,不妨告知我一下。

那么言归正传,如何测量图像的宽度呢,我们先将图像进行预处理,不外乎将彩色图转化为灰度图,图像平滑处理,图像形态学运算,二值化等等。又跑偏话题了。

举例我们得到一幅如下的二值图像。

基于OpenCV的图像测量_第2张图片

如何测量白色区域的宽度呢?

方法如下:可以将图像看成一个二维数组,从第一行开始,找到第一行从黑色转化成白色的点的横坐标,再去找第一行从白色转化成黑色的点的横坐标。两者之差就是图像的宽度。第一行处理完毕,继续处理第二第三行等等。思想很简单,代码不长,也不做过多的解释。如有问题,可以留言。


#include "stdio.h"
#include "cv.h" 
#include "highgui.h"  
#include <cxcore.hpp>
#include <afxcom_.h>

using namespace cv;
using namespace std;

int main()
{
	IplImage* src;
	src=cvLoadImage("bin.jpg",CV_LOAD_IMAGE_GRAYSCALE);
	cvThreshold( src, src,80, 255, CV_THRESH_BINARY );//二值化

	int width=src->width;
	int height=src->height;

	BOOL bFirst=FALSE;
	int  x1,x2;
	for (int j=1;j<height;++j)
	{
		for (int i=1;i<width;++i)
		{	
			int  tempElem;
			tempElem=CV_IMAGE_ELEM(src,byte,j,i);
			ASSERT(tempElem==0||tempElem==255);
			if (CV_IMAGE_ELEM(src,byte,j,i)>0&&CV_IMAGE_ELEM(src,byte,j,i-1)==0)
			{
				x1=i;
			}
			if (CV_IMAGE_ELEM(src,byte,j,i)==0&&CV_IMAGE_ELEM(src,byte,j,i-1)>0)
			{
				x2=i;
				printf("x1=%d, x2=%d ,y=%d ,Image width=%d \n",x1,x2,j,x2-x1);
			}
		}
	}

	cvNamedWindow( "Source", 1 );
	cvShowImage( "Source", src );
	cvWaitKey(0);
	cvDestroyWindow( "Source" );
	cvReleaseImage(&src);
	return 0;
}

测试结果图片如下。

基于OpenCV的图像测量_第3张图片

完!

你可能感兴趣的:(基于OpenCV的图像测量)