opencv我自己的二维条形码阅读器

时间:2013-08-27 01:51:52

标签: opencv barcode pixel

未在谷歌找到答案,请求您的帮助:我需要制作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 ......你有什么建议吗?谢谢。

2 个答案:

答案 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
    }
}

更好的解决方案可能是使用findContoursminAreaRect,这应该围绕每一行创建一个矩形:

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
}