2013-08-27 33 views
-3

沒有在Google上找到答案,所以要求你的幫助:我需要製作C++程序來識別2D自己! (密碼)條碼(手工編碼)。它由20-100行組成。每一行 - 一個字。opencv我自己的2D條形碼閱讀器

預計使用OpenCV。需要找到圖像組的條形圖,從左上角裁剪和掃描圖片。

作物和代碼搜索沒有問題。不明白,如何正確識別黑色和白色像素線,以獲得每條線的獨特組合。

正如我anderstand,好辦法 - 用線去看看白色像素或黑色,如果黑 - 寫1,如果白= 0 ....比寫順序是這樣的:

11111111 000000 111111 00000000000 111111111111111 0000000 1111 = 8 6 6 11 15 7 4(計數1和0數量)=得到866111574比使用係數取決於作物的寬度和高度來找到一致。

如何使用Opencv在C++代碼中編寫此代碼?不明白。試圖使用cvInitLineIterator ...你有什麼建議?謝謝。

+0

原因downvote。沒有測試圖像,你還沒有開始學習opencv。沒有你提供的代碼,這讓我懷疑你已經付出了適當的努力,谷歌「如何在opencv迭代圖像」。如果你擊敗了你的項目的每一個需求,你會發現在stackoverflow,谷歌等豐富的資源等。從這裏學習一些教程opencv:http://docs.opencv.org/3.1.0/,嘗試Python,除非你是C比Python更好。我會建議安德魯高度回答,特別是在分析條形碼之前計算拐角和單應計算。 – saurabheights

回答

1

你還沒有提供任何圖片或代碼片段,所以不是很清楚你現在擁有的圖案。
一些一般的想法:

1)搜索你的代碼角落。

2)計算homograpy。

3)應用homograpy變換來獲得您的代碼的方形圖像。

4)你應該知道你的代碼行(或行數)的步驟,所以只需將圖像分爲水平行。

5)獲取每一行的投資回報率。計算垂直軸上的像素總和(cv :: reduce)(以獲得一些統計數據)。現在你有1條帶白色和黑色區域的水平線。

6)將此線設計爲N個(碼字長度),然後計算每片中的像素總和。

7)應用閾值,你得到你的代碼。

+0

謝謝你的回答,代碼看起來像QR碼有一些差異。關於線條:我在設置中使用程序之前選擇線條數量(字數量)。讓它成爲100行。條形碼有10個柱面。一個黑色條可以使用1列,可以使用2列或3列。酒吧之間也有不同的距離。沒有在Opencv中找到在桌面上分割圖像的能力。可以adwise東西? – WorkStudio

+0

您可以使用矩陣操作設置投資回報率,這很容易,看看http://stackoverflow.com/questions/4031233/in-opencv-2-1-how-to-assign-a-matrix-to-a另一種矩陣的矩陣但是還有另一種方法。如果你知道數據條的位置,你可以使用帶有條索引的掩碼。只需使用等於此欄的索引的值填充欄的位置即可。那麼你只需要閱讀它,並在同一位置的圖像像素值。 –

+0

您如何看待,更好地使用條形識別的方法?我的程序現在可以從上到下掃描照片,並以1 px的降低量繪製ROI矩形1像素高度和100%寬度。我想使用直方圖比較每個1像素ROI內的圖像來找到與模型條圖片匹配的內容,但它是否足夠快速和正確,還是可以提供更好的建議? – WorkStudio

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 
} 
+0

謝謝你的例子,但「minRect.size.width確定欄的寬度」 - 這是第一個問題......但是黑色條之間的白色區域的寬度如何?它也很重要。或者,可能需要使用任何遮罩實例與實例相比較? – WorkStudio

+0

您可以將RotatedRect放入一個向量中,然後使用'std :: sort'通過_rect.center.x_座標進行排序。所以現在你有從左到右排列的矩形。然後,您可以循環低谷並提取它們之間的距離(使用_rect.center.x_和_rect.width_)。如果你需要幫助如何排序矢量問問。 –

+0

現在我看到你有多行條形碼。在這種情況下,過程與以前類似,只需按X進行排序,然後按Y座標進行排序。向量將從左到右和從上到下具有矩形的序列。 –