本工程是利用OpenCV4.5.4进行图像预处理,将条形码找到并送进ZBar进行识别 目前能实现对干扰少的多条形码图片进行是被,后期希望能够利用摄像头在有干扰的情况下对条形码进行识别
工程代码
#include <iostream>
#include <opencv2/opencv.hpp>
#include <zbar.h>
using namespace std;
using namespace cv;
using namespace zbar;
int main()
{
ImageScanner scanner;
while (1)
{
Mat image_s, image_gray, image_gradX, image_gradY, image_grad;
image_s = imread("多条形码.jpg", 1);
imshow("source", image_s);
cvtColor(image_s, image_gray, COLOR_BGR2GRAY);
imshow("gray", image_gray);
Scharr(image_gray, image_gradX, CV_8U, 1, 0);
Scharr(image_gray, image_gradY, CV_8U, 0, 1);
subtract(image_gradX, image_gradY, image_grad);
imshow("grad", image_grad);
Mat image_threshold;
threshold(image_grad, image_threshold, 100, 255, THRESH_BINARY);
Mat element = getStructuringElement(1, Size(9, 9));
dilate(image_threshold, image_threshold, element);
dilate(image_threshold, image_threshold, element);
erode(image_threshold, image_threshold, element);
erode(image_threshold, image_threshold, element);
morphologyEx(imageSobleOutThreshold, imageSobleOutThreshold, MORPH_CLOSE, element);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(imageSobleOutThreshold, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);
for (int i = 0; i < contours.size(); i++)
{
double TempArea = fabs(contourArea(contours[i]));
if (TempArea > 1000)
{
Rect rect = boundingRect(contours[i]);
rectangle(image_s, rect, Scalar(255), 2);
Mat image_roi = image_gray(rect);
Mat image_scan;
image_roi.copyTo(image_scan);
int width = image_scan.cols;
int height = image_scan.rows;
uchar* image_zbar = (uchar*)image_scan.data;
Image imageZbar(width, height, "Y800", image_zbar, width * height);
scanner.scan(imageZbar);
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;
}
imageZbar.set_data(NULL, 0);
}
}
imshow("end", image_s);
cout << "--------------------" << endl;
if (waitKey(10) == 'q');
}
return 0;
}
运行效果
在编写过程中遇到的最大的问题就是在利用Opencv画出Roi区域后转换为ZBar的图像类型进行识别总是会识别出同一排的其他二维码。 出现这种问题的原因是因为在划定Roi区域的时候并不会划定一块新的区域来储存图像,而是指向原来的图像,相当于将原图送到了ZBar进行识别,解决方法是利用copyTo()将划定的Roi区域储存在新的图像变量中。 详细解释: openCV_C++笔记 : ROI感兴趣区域与Rect类 关于opencv中ROI区域的理解
|