zoukankan      html  css  js  c++  java
  • Opencv:10个步骤检测出图片中条形码

    1. 原图像大小调整,提高运算效率



    2. 转化为灰度图



    3. 高斯平滑滤波



    4.求得水平和垂直方向灰度图像的梯度差,使用Sobel算子



    5.均值滤波,消除高频噪声



    6.二值化



    7.闭运算,填充条形码间隙



    8. 腐蚀,去除孤立的点



    9. 膨胀,填充条形码间空隙,根据核的大小,有可能需要2~3次膨胀操作



    10.通过findContours找到条形码区域的矩形边界



    实现:

    #include "core/core.hpp"
    #include "highgui/highgui.hpp"
    #include "imgproc/imgproc.hpp"
    
    using namespace cv;
    
    int main(int argc,char *argv[])
    {
    	Mat image,imageGray,imageGuussian;
    	Mat imageSobelX,imageSobelY,imageSobelOut;
    	image=imread(argv[1]);
    
    	//1. 原图像大小调整,提高运算效率
    	resize(image,image,Size(500,300));
    	imshow("1.原图像",image);
    
    	//2. 转化为灰度图
    	cvtColor(image,imageGray,CV_RGB2GRAY);
    	imshow("2.灰度图",imageGray);
    
    	//3. 高斯平滑滤波
    	GaussianBlur(imageGray,imageGuussian,Size(3,3),0);
    	imshow("3.高斯平衡滤波",imageGuussian);
    
    	//4.求得水平和垂直方向灰度图像的梯度差,使用Sobel算子
    	Mat imageX16S,imageY16S;
    	Sobel(imageGuussian,imageX16S,CV_16S,1,0,3,1,0,4);
    	Sobel(imageGuussian,imageY16S,CV_16S,0,1,3,1,0,4);
    	convertScaleAbs(imageX16S,imageSobelX,1,0);
    	convertScaleAbs(imageY16S,imageSobelY,1,0);
    	imageSobelOut=imageSobelX-imageSobelY;
    	imshow("4.X方向梯度",imageSobelX);
    	imshow("4.Y方向梯度",imageSobelY);
    	imshow("4.XY方向梯度差",imageSobelOut);	
    
    	//5.均值滤波,消除高频噪声
    	blur(imageSobelOut,imageSobelOut,Size(3,3));
    	imshow("5.均值滤波",imageSobelOut);	
    
    	//6.二值化
    	Mat imageSobleOutThreshold;
    	threshold(imageSobelOut,imageSobleOutThreshold,180,255,CV_THRESH_BINARY);	
    	imshow("6.二值化",imageSobleOutThreshold);
    
    	//7.闭运算,填充条形码间隙
    	Mat  element=getStructuringElement(0,Size(7,7));
    	morphologyEx(imageSobleOutThreshold,imageSobleOutThreshold,MORPH_CLOSE,element);	
    	imshow("7.闭运算",imageSobleOutThreshold);
    
    	//8. 腐蚀,去除孤立的点
    	erode(imageSobleOutThreshold,imageSobleOutThreshold,element);
    	imshow("8.腐蚀",imageSobleOutThreshold);
    
    	//9. 膨胀,填充条形码间空隙,根据核的大小,有可能需要2~3次膨胀操作
    	dilate(imageSobleOutThreshold,imageSobleOutThreshold,element);
    	dilate(imageSobleOutThreshold,imageSobleOutThreshold,element);
    	dilate(imageSobleOutThreshold,imageSobleOutThreshold,element);
    	imshow("9.膨胀",imageSobleOutThreshold);		
    	vector<vector<Point>> contours;
    	vector<Vec4i> hiera;
    
    	//10.通过findContours找到条形码区域的矩形边界
    	findContours(imageSobleOutThreshold,contours,hiera,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
    	for(int i=0;i<contours.size();i++)
    	{
    		Rect rect=boundingRect((Mat)contours[i]);
    		rectangle(image,rect,Scalar(255),2);	
    	}	
    	imshow("10.找出二维码矩形区域",image);
    
    	waitKey();
    }

    使用另一幅图片的效果如下:



    底部的二维码左侧边界定位错位,检测发现在二值化的时候左侧第二个条码部分被归零了,导致在之后的腐蚀操作中被腐蚀掉了。调整阈值分界值180到160,重新运行正确:


  • 相关阅读:
    【Language】 TIOBE Programming Community Index for February 2013
    【diary】good health, good code
    【web】a little bug of cnblog
    【Git】git bush 常用命令
    【web】Baidu zone ,let the world know you
    【diary】help others ,help yourself ,coding is happiness
    【Git】Chinese messy code in widows git log
    【windows】add some font into computer
    SqlServer启动参数配置
    关于sqlserver中xml数据的操作
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9411996.html
Copyright © 2011-2022 走看看