3

光学式マーク認識の問題に取り組んでいます。私は学生のロールナンバーを記入する領域(ROI)を見つけました。どのアプローチが満員円の価値を解読するのに役立ちますか?私はコードしようとしましたが、正しく機能していません。OCRマーカーを検出する

このイメージ初期ROI内の画像

は私がsegmentation.Thirdイメージが学生のロール番号を示す学生が満たされて適用されていることをgiven.Afterです。

この画像は381円が、実際の円を検出している100

Input: Filled circle image 
Output: roll number : 4216789503 

image = cv2.imread("rotatedb/ROI_omr.png") 
hsvimg = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 
lower_blue = np.array([0,70,0]) 
upper_blue = np.array([255,255,255]) 
mask = cv2.inRange(hsvimg, lower_blue, upper_blue) 
contours, hierarchy = cv2.findContours(mask.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) 
print "No. of circles",len(contours) 

i=0 
for contour in contours: 
    (x,y),radius = cv2.minEnclosingCircle(contour) 
    center = (int(x),int(y)) 
    radius = int(radius) 
    cv2.circle(image,center,radius,(0,255,0),2) 
    position = (center[0] - 10, center[1] + 10) 
    text_color = (0, 0, 255) 
    cv2.putText(image, str(i + 1), position, cv2.FONT_HERSHEY_SIMPLEX, 0.5, text_color, 2) 
    i=i+1 

cv2.imshow("thresold",image) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 
+1

ではなく 'cv2.RETR_TREE'の "外部" フラグを使用します。 – Micka

答えて

1

マーカーは黒色であり、だから、入力画像中の黒色のセグメントのセグメントしようとすべきであるように、そのバイナリマスクあなたから輪郭を見つけて円形の輪郭をフィルタリングすることができます(輪郭を領域でフィルタリングしたい場合もあります)。

すべての輪郭を見つけた後、そのxごとに輪郭を並べ替えることが常にあるので、ランダムな順序でcv2.findContours()返し輪郭(私たちは、水平方向にそれらを横断しているとして、私たちの輪郭の順序をもたらすことになる、RECT境界の座標

最後に、各輪郭の中間点を計算し、それらの輪郭を推定します。

コード:

import cv2 

img = cv2.imread('/Users/anmoluppal/Downloads/QYtuv.png') 
MARKER_LOWER_BOUND = (0, 0, 0) 
MARKER_UPPER_BOUND = (20, 20, 20) 

img = cv2.blur(img, (7, 7)) 
marker_seg_mask = cv2.inRange(img, MARKER_LOWER_BOUND, MARKER_UPPER_BOUND) 

# Number of rows and columns of number matrix 
n_rows, n_cols = 10, 10 
single_element_height, single_element_width = marker_seg_mask.shape[0]/10, marker_seg_mask.shape[1]/10 

# Now find the contours in the segmented mask 
img, contours, hierarchy = cv2.findContours(marker_seg_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 

# Sorting the contours w.r.t contour rect X 
contours.sort(key = lambda x:cv2.boundingRect(x)[0]) 

# Now iterate over each contour and see if it is in circular shape 
roll_number = "" 
for contour in contours: 
    approx = cv2.approxPolyDP(contour, 0.01*cv2.arcLength(contour,True), True) 
    if len(approx) > 8: 
     # Find the bounding rect of contour. 
     contour_bounding_rect = cv2.boundingRect(contour) 
     mid_point = contour_bounding_rect[0] + contour_bounding_rect[2]/2, contour_bounding_rect[1] + contour_bounding_rect[3]/2 
     roll_num_digit = mid_point[1]/single_element_height 

     # Since your numbering format is from 1, 2, 3, ... 0, So to parse the roll number correctly we need additional operation 
     roll_num_digit = (roll_num_digit + 1) % 10 
     roll_number += str(roll_num_digit) 
print "Roll Number: ", roll_number 

出力:findContoursで

Roll Number: 4216789503 
+1

OpenCV2.x APIを使用している可能性があり、OpenCV 3.1.0でコードを書いていますが、OpenCV2.xのような小さな違いがあるかもしれません。 'cv2.findContours()'は2つのオブジェクトを 'contours、hierarchy'この行を 'contours、hierarchy = cv2.findContours(marker_seg_mask.copy()、cv2.RETR_EXTERNAL、cv2.CHAIN_APPROX_NONE)に置き換える必要があります。 ' – ZdaR

+0

それでは問題は何ですか?あなたは '4216789503'で新しい画像をアップロードできますか? – ZdaR

+0

このスニペットの現在の出力は何ですか?期待される成果は? – ZdaR

関連する問題