Ubuntu上使用vscode以及opencv库和zbar库基于c++进行条形码识别

识别条形码,首先我们需要考虑到识别图片的大小以及干扰因素等等。

因此我们需要进行的操作主要有三个部分:

目录

1、图片平滑降噪

2、根据目标特征运算

3、图片定位与识别


进行以下操作,首先要确保opencv库以及zbar库正常安装。有疑问可以参考笔者关于opencv以及zbar配置的文章


1、图片平滑降噪

首先我们需要使用到以下头文件

#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include "zbar.h"
#include "opencv.hpp"
#include <iostream>

还需要声明命名空间

using namespace std;
using namespace cv;
using namespace zbar;

读取图像并进行平滑降噪处理

    //读取文件
    Mat img = imread("1.jpg")//1.jpg是处在工作目录下的jpg文件名称
    Mat imgGrey;

    //转化为灰度图,方便运算与识别
    cvtColor(img, imgGray, COLOR_RGB2GRAY);

    // 高斯平滑滤波
    Mat imgGus;
    GaussianBlur(imgGray, imgGus, Size(3,3), 0);

    //4.求得水平和垂直方向灰度图像的梯度差,使用Sobel算子
	Mat imageX16S, imageY16S;
	Sobel(imgGus, imageX16S, CV_16S, 1, 0, 3, 1, 0, 4);
	Sobel(imgGus, imageY16S, CV_16S, 0, 1, 3, 1, 0, 4);
	convertScaleAbs(imageX16S, imageSobelX, 1, 0);
	convertScaleAbs(imageY16S, imageSobelY, 1, 0);
	imageSobelOut=imageSobelX-imageSobelY;

 
	//5.均值滤波,消除高频噪声
    Mat imgBlur;
	blur(imageSobelOut, imgBlur, Size(3,3));

 
	//6.二值化
	Mat imgThreshold;
	threshold(imgBlur,imgThreshold,80,255,THRESH_BINARY);

2、根据目标特征运算

首先、条形码在前面的处理降噪之后,我们需要让其中间的空隙连起来形成一个长方形块,方便对其定位,因此使用闭运算填充条形码间隙

//闭运算,填充条码间隙
Mat element = getStructuringElement(0,Size(7,7));//闭运算需要的参数
morphologyEx(imgThreshold,imgThreshold,MORPH_CLOSE,elementmor);	

紧接着,进行腐蚀,去除孤立的点以及线

    // 腐蚀,去除孤立的点
    Mat  elementero1=getStructuringElement(0,Size(60,3));//此处的size()参数要根据图像特征进行调整
	erode(imgThreshold,imgThreshold,elementero1);

最后,将剩下的筛选出来的条形码块进行膨胀拓宽,达到符合条形码轮廓的大小

    // 膨胀,根据目标条形码的大小,需要多次膨胀操作,具体次数随情况变化
    Mat  elementdli=getStructuringElement(0,Size(30,7));
	dilate(imgThreshold,imgThreshold,elementdli);
    dilate(imgThreshold,imgThreshold,elementdli);
    dilate(imgThreshold,imgThreshold,elementdli);
    dilate(imgThreshold,imgThreshold,elementdli);
    dilate(imgThreshold,imgThreshold,elementdli);

3、图片定位与识别

    vector<vector<Point>> contours;
	vector<Vec4i> hiera;
	findContours(imageSobleOutThreshold,contours,hiera,RETR_EXTERNAL,CHAIN_APPROX_NONE);
	Mat scanimg[contours.size()];
	for(int i=0;i<contours.size();i++)//contours is the contour of my image 
	{
		Rect rect=boundingRect((Mat)contours[i]);//rect is a coordinate,it's has 4 
                                                 //element
		rectangle(image,rect,Scalar(255),2);
		cout<<"a"<<endl;
		scanimg[i] = image(rect);//image accoding to the rect to cut the pictrue
		//process come to here ,things we need do to pictrue is 
	    cvtColor(scanimg[i], scanimg[i], COLOR_RGB2GRAY);
		string o = num2str(i);
		imshow(o, scanimg[i]);
	    //already done,the next step is Identify barcode

		ImageScanner scanner;    
		scanner.set_config(ZBAR_NONE, ZBAR_CFG_ENABLE, 1); 
		int width = scanimg[i].cols;    
		int height = scanimg[i].rows;    
		uchar *raw = (uchar *)scanimg[i].data;       
		Image imageZbar(width, height, "Y800", raw, width * height);      
		scanner.scan(imageZbar); //扫描条码  
		Image::SymbolIterator symbol = imageZbar.symbol_begin();
		if(imageZbar.symbol_begin()==imageZbar.symbol_end())
		{
			cout<<"查询条码失败,图片清晰度不足!"<<endl;
		}
		for(;symbol != imageZbar.symbol_end();++symbol)  
		{    
			cout<<"类型:"<<endl<<symbol->get_type_name()<<endl<<endl;  
			cout<<"条码:"<<endl<<symbol->get_data()<<endl<<endl;     
		} 
	}

需要完整代码可以留言,有需要笔者会发出来。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值