未在谷歌找到答案,请求您的帮助:我需要制作C ++程序来识别自己的2D! (密码)条形码(手工制作的代码)。它由20-100行组成。每一行 - 一个字。
决定使用OpenCV。需要找到图像组的条形图,从左上角裁剪和扫描图片。
裁剪和代码搜索没问题。不明白,如何正确识别黑白像素线,以获得每一行的独特组合。
正如我理解的那样,好的方法 - 逐行看到白色像素或黑色,如果是黑色 - 写1,如果白色= 0 ....而不是像这样写序列:
11111111 000000 111111 00000000000 111111111111111 0000000 1111 = 8 6 6 11 15 7 4(计数1和0数量)=得到866111574比使用系数取决于作物宽度和高度来寻找合规。
如何使用Opencv在C ++代码中编写此代码?不明白。试图使用cvInitLineIterator ......你有什么建议吗?谢谢。
答案 0 :(得分:1)
您还没有提供任何图片或代码片段,所以现在还不是很清楚 一些一般性的想法:
1)搜索代码角落。
2)计算单词。
3)应用homograpy变换来获得代码的方形图像。
4)你应该知道你的代码行数(或行数),所以只需将图像分成水平线。
5)获得每一行的投资回报率。沿垂直轴计算像素总和(cv :: reduce)(得到一些统计数据)。现在你有1条带有白色和黑色区域的水平线。
6)将这一行划分为N个(代码字长),然后计算每个部分的像素总和。
7)应用阈值,然后获取代码。
答案 1 :(得分:1)
你可以迭代这样的像素:
uchar pixel = 0;
Mat img; // this must be grayscale image - type CV_8U
for(int i=0; i<img.rows; i++)
{
// this loop is iterating from left to right
for(int j=0; i<img.cols; j++)
{
pixel = img.at<uchar>(i,j);
// do something (e.g. sum pixels)
// OpenCV doesn't have binary image type, so usually white pixels value is 255
}
}
更好的解决方案可能是使用findContours和minAreaRect,这应该围绕每一行创建一个矩形:
vector<vector<Point>> vecContours;
vector<Vec4i> hierarchy;
RotatedRect currentRect;
Mat binaryImage = imread(...)
// binaryImage should contain only shapes or edges, I suggest using one of these approaches:
// simple binary tresholding, try different threshold_value
threshold(binaryImage, binaryImage, threshold_value, 255, THRESH_BINARY);
// adaptiveTreshold works better when image is varying in brightness
// adjust blockSize and C (start with C=0)
adaptiveThreshold(binaryImage, binaryImage, 255, ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, blockSize, C);
// another option would be to use Canny edge detector:
// http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html
// find external contours, binaryImage = grayscale 8-bit image
// binaryImage is modified during findContours so we create a clone
findContours(binaryImage.clone(), vecContours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
// find minAreaRect for each contour (each line)
for (size_t = 0; i < vecContours.size(); i++)
{
// filter unwanted objects (contours with less than 4 points, contours with too small area)
if (vecContours[i].size() < 4 || contourArea(vecContours[i]) < someAreaInPixels)
continue;
// you can draw contours for debugging
// drawContours(binaryImage, vecContours, i, Scalar(255,0,0), 1, 8, hierarchy, 0, Point());
RotatedRect minRect = minAreaRect(vecContours.at(i));
// now you can use minRect.size.width to determine width of the bar
// minRect contains center point, size and angle
}