2017-08-19 18 views
2

私は手書き数字のスキャンされたイメージを長方形(小さなもの)の中にたくさん持っています。 Like Thisイメージとクロップの矩形を検出

数字を含む各画像をトリミングし、各行に同じ名前を付けて保存してください。

編集

import cv2 

img = cv2.imread('Data\Scan_20170612_4.jpg') 

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
gray = cv2.bilateralFilter(gray, 11, 17, 17) 
edged = cv2.Canny(gray, 30, 200) 

_, contours, hierarchy = cv2.findContours(edged, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) 

i = 0 
for c in contours: 
    peri = cv2.arcLength(c, True) 
    approx = cv2.approxPolyDP(c, 0.09 * peri, True) 

    if len(approx) == 4: 
     screenCnt = approx 
     cv2.drawContours(img, [screenCnt], -1, (0, 255, 0), 3) 
     cv2.imwrite('cropped\\' + str(i) + '_img.jpg', img) 

     i += 1 
+0

最初のショーですがあなたのコード、何を試してみましたか? – Kallz

+0

@Kallz私は編集で試したコードを提供しました – utkarsh

+0

ハフ変換を使ってメインラインの向きを見つけることで回転を元に戻すこともできます。 – RobAu

答えて

0

マイバージョン

import cv2 
import numpy as np 

fileName = ['9','8','7','6','5','4','3','2','1','0'] 

img = cv2.imread('Data\Scan_20170612_17.jpg') 

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
gray = cv2.bilateralFilter(gray, 11, 17, 17) 

kernel = np.ones((5,5),np.uint8) 
erosion = cv2.erode(gray,kernel,iterations = 2) 
kernel = np.ones((4,4),np.uint8) 
dilation = cv2.dilate(erosion,kernel,iterations = 2) 

edged = cv2.Canny(dilation, 30, 200) 

_, contours, hierarchy = cv2.findContours(edged, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 

rects = [cv2.boundingRect(cnt) for cnt in contours] 
rects = sorted(rects,key=lambda x:x[1],reverse=True) 


i = -1 
j = 1 
y_old = 5000 
x_old = 5000 
for rect in rects: 
    x,y,w,h = rect 
    area = w * h 

    if area > 47000 and area < 70000: 

     if (y_old - y) > 200: 
      i += 1 
      y_old = y 

     if abs(x_old - x) > 300: 
      x_old = x 
      x,y,w,h = rect 

      out = img[y+10:y+h-10,x+10:x+w-10] 
      cv2.imwrite('cropped\\' + fileName[i] + '_' + str(j) + '.jpg', out) 

      j+=1 
0
_, contours, hierarchy = cv2.findContours(edged, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) 

あなたはイメージで輪郭を見つけるために、cv2.RETR_LISTを使用しています。イメージがより良い出力を得るには、cv2.RETR_EXTERNALを使用してください。最初にそれを使用する前に黒から国境ラインを削除します。

cv2.RETR_LISTは

_, contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 

Contours Hierarchyにあなた

変更ラインを唯一の外部または外側の輪郭ではなく、内部の輪郭を与えるあなたのイメージ

cv2.RETR_EXTERNALためのすべての輪郭のリストを与えます

2

これは簡単なことですが、試してみてください。ここに私の出力 - (画像とその一つの小さなビット)私がやったこと

enter image description here

ですか?それは右のポイントから始まる、画像

  • 洪水がいっぱいしきい値を小さなドットを削除し、ライン
  • を厚くするために、拡張を侵食
  • 私の画面ではあまりにも大きかったので、最初の画像をリサイズ

    1. フラッドフィルを反転する
    2. 輪郭を見つけて、長方形のおよそ の範囲内にある輪郭を一度に1つずつ描きます。私のサイズ変更された(500x500)イメージの場合、範囲は500〜2500(試行錯誤のように)の 輪郭の範囲を入れます。
    3. 境界の矩形を見つけ、メインイメージからそのマスクをトリミングします。
    4. 次に、私がしなかった適切な名前でその部分を保存します。

      多分、もっと簡単な方法がありますが、私はこれが好きでした。コードを入れないので 私はそれをすべて不器用にしました。あなたがまだそれを必要とする場合は入れます。

      ここでは、輪郭たびに

    enter image description here

    コード見つけたときのマスクがどのように見えるかです:ここでは

    import cv2; 
    import numpy as np; 
    
    # Run the code with the image name, keep pressing space bar 
    
    # Change the kernel, iterations, Contour Area, position accordingly 
    # These values work for your present image 
    
    img = cv2.imread("your_image.jpg", 0); 
    h, w = img.shape[:2] 
    kernel = np.ones((15,15),np.uint8) 
    
    e = cv2.erode(img,kernel,iterations = 2) 
    d = cv2.dilate(e,kernel,iterations = 1) 
    ret, th = cv2.threshold(d, 150, 255, cv2.THRESH_BINARY_INV) 
    
    mask = np.zeros((h+2, w+2), np.uint8) 
    cv2.floodFill(th, mask, (200,200), 255); # position = (200,200) 
    out = cv2.bitwise_not(th) 
    out= cv2.dilate(out,kernel,iterations = 3) 
    cnt, h = cv2.findContours(out,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 
    for i in range(len(cnt)): 
          area = cv2.contourArea(cnt[i]) 
          if(area>10000 and area<100000): 
            mask = np.zeros_like(img) 
            cv2.drawContours(mask, cnt, i, 255, -1) 
            x,y,w,h = cv2.boundingRect(cnt[i]) 
            crop= img[ y:h+y,x:w+x] 
            cv2.imshow("snip",crop) 
            if(cv2.waitKey(0))==27:break 
    
    cv2.destroyAllWindows() 
    
  • +0

    コードを投稿してください – utkarsh

    +0

    コードを追加しましたが、あなたの大きな画像と闘わなければなりませんでした –

    関連する問題