前言
本文将介绍在vs平台上OpenCV联合Halcon,实现包装袋的日期识别。本文仅供学习和参考,若有不妥的地方,欢迎友善指出。
本示例分为三部分,第一部分介绍使用OpenCV提取目标区域,第二部分介绍使用Halcon的OCR进行日期识别,第三部分将整合OpenCV与Hanlcon。
先对图像进行预处理:
#include<iostream>
#include<opencv2/opencv.hpp>
#include<vector>
using namespace std;
using namespace cv;
int main()
{
int ret = 0;
Mat img = imread("C:\\Users\\Public\\Pictures\\baozhuang03.jpg");
//imshow("test", img);
Mat imgGray, imgBlur, imgCanny, imgDil, imgErode, imgSobel, imgClose;
//图像预处理
cvtColor(img, imgGray, COLOR_BGR2RGBA);
GaussianBlur(imgGray, imgBlur, Size(5, 5), 5, 0);
threshold(imgBlur, imgBlur, 130, 255,THRESH_BINARY );
Mat kernel = getStructuringElement(0, Size(35, 35));
morphologyEx(imgBlur, imgClose, MORPH_CLOSE, kernel);
Canny(imgClose, imgCanny, 30, 30);
Mat kernel2 = getStructuringElement(0, Size(5, 5));
dilate(imgCanny, imgDil, kernel2);
waitKey(0);
system("pause");
return 0;
}
二值化
闭运算
Canny边缘检测
Dilate膨胀运算
接下来选取轮廓:
使用findContours提取预处理后的轮廓,通过筛选图像的轮廓面积,就能定位到日期所在位置,当然,也可以用矩形的长宽比来筛选。
//找轮廓
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
findContours(imgDil, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
//drawContours(img, contours, -1, Scalar(0, 255, 0), 2);
for (int i = 0; i < contours.size(); i++) {
int area = contourArea(contours[i]);
//cout << area << endl;
vector<vector<Point>>conPoly(contours.size());
vector<Rect>boundRect(contours.size());
//根据面积筛选
if (area > 14000 && area < 15000) {
float peri = arcLength(contours[i], true);
approxPolyDP(contours[i], conPoly[i], 0.02*peri, true);
RotatedRect rrect = minAreaRect(conPoly[i]);
Point2f points[4];
rrect.points(points);
Point2f cpt = rrect.center;
for (int i = 0; i < 4; i++) {
if (i == 3)
{
line(img, points[i], points[0], Scalar(0, 255, 0), 1, 8, 0);
break;
}
line(img, points[i], points[i + 1], Scalar(0, 255, 0), 1, 8, 0);
}
}
}
如图被绿色框出区域为所需要检测的日期。
最后将目标区域截取出来,并保存备用:
定位到日期所在位置后,使用反射变换等,将目标区域提取出来,并矫正。
//反射变换
float w = 500, h = 40;
Mat matrix, imgWarp;
Point2f src[4] = { points[0],points[1],points[3],points[2] };
Point2f dst[4] = { {0.0f,0.0f},{w,0.0f},{0.0f,h},{w,h} };
matrix = getPerspectiveTransform(src, dst);
warpPerspective(img, imgWarp, matrix, Point(w, h));
flip(imgWarp, imgWarp, -1);
imshow("Image Warp", imgWarp);
imwrite("01.jpg", imgWarp);
小结
本节内容,是用OpenCV将目标区域提取出来,但由于不同图像需要根据本身图像特征设定预处理算法,所以,本案例的一个缺点就是不具有鲁棒性,只针对特定需求。
下一篇链接: