1

원/십자가가있는 격자 요소 또는 내부에 채워진 요소를 찾으려고합니다. 논리를 구축하기 위해 here의 코드를 사용했습니다.채워진 격자 요소 찾기

로직 - 그리드 coorindates 찾기 -> 각 사각형 블록의 상단 왼쪽 및 하단 오른쪽 꼬임을 사용하여 격자 요소의 하위 이미지 추출 -> 0이 아닌 픽셀 수 찾기 -> 사각형이 50 % 이상 채워지면 채워진대로

격자가 비어 있으면 모든 격자 좌표를 성공적으로 찾을 수 있습니다. 그러나 격자 요소가 채워지면 이미지에서 볼 수있는 것처럼 예상대로 작동하지 않습니다. 이 코드를 수정하여 매번 모든 그리드 coorindate를 성공적으로 결정할 수 있습니까?

image.png res2.png res3.png res4.png res5.png res6.png

import cv2 
import cv 
import numpy as np 
import operator 
from PIL import Image 
import math 


region = cv2.imread("image.png") 
img = cv2.GaussianBlur(region,(5,5),0) 
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
mask = np.zeros((gray.shape),np.uint8) 
kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11)) 

close = cv2.morphologyEx(gray,cv2.MORPH_CLOSE,kernel1) 
div = np.float32(gray)/(close) 
res = np.uint8(cv2.normalize(div,div,0,255,cv2.NORM_MINMAX)) 
res2 = cv2.cvtColor(res,cv2.COLOR_GRAY2BGR) 

##finding rectangles & creating mask image 
thresh = cv2.adaptiveThreshold(res,255,0,1,19,2) 
contour,hier = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 

max_area = 0 
best_cnt = None 
for cnt in contour: 
    area = cv2.contourArea(cnt) 
    if area > 1000: 
     if area > max_area: 
      max_area = area 
      best_cnt = cnt 

cv2.drawContours(mask,[best_cnt],0,255,-1) 
cv2.drawContours(mask,[best_cnt],0,0,2) 

res = cv2.bitwise_and(res,mask) 
cv2.imwrite("res2.png",res) 

##Finding vertical lines 
kernelx = cv2.getStructuringElement(cv2.MORPH_RECT,(2,10)) 

dx = cv2.Sobel(res,cv2.CV_16S,1,0) 
dx = cv2.convertScaleAbs(dx) 
cv2.normalize(dx,dx,0,255,cv2.NORM_MINMAX) 
ret,close = cv2.threshold(dx,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 
close = cv2.morphologyEx(close,cv2.MORPH_DILATE,kernelx,iterations = 1) 

contour, hier = cv2.findContours(close,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) 
for cnt in contour: 
    x,y,w,h = cv2.boundingRect(cnt) 
    if h/w > 5: 
     cv2.drawContours(close,[cnt],0,255,-1) 
    else: 
     cv2.drawContours(close,[cnt],0,0,-1) 
close = cv2.morphologyEx(close,cv2.MORPH_CLOSE,None,iterations = 2) 
closex = close.copy() 
cv2.imwrite("res3.png",closex) 

##Finding horizontal lines 
kernely = cv2.getStructuringElement(cv2.MORPH_RECT,(10,2)) 
dy = cv2.Sobel(res,cv2.CV_16S,0,2) 
dy = cv2.convertScaleAbs(dy) 
cv2.normalize(dy,dy,0,255,cv2.NORM_MINMAX) 
ret,close = cv2.threshold(dy,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 
close = cv2.morphologyEx(close,cv2.MORPH_DILATE,kernely) 

contour, hier = cv2.findContours(close,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) 
for cnt in contour: 
    x,y,w,h = cv2.boundingRect(cnt) 
    if w/h > 5: 
     cv2.drawContours(close,[cnt],0,255,-1) 
    else: 
     cv2.drawContours(close,[cnt],0,0,-1) 

close = cv2.morphologyEx(close,cv2.MORPH_DILATE,None,iterations = 2) 
closey = close.copy() 
cv2.imwrite("res4.png",closey) 

##Finding grid points 
res = cv2.bitwise_and(closex,closey) 
cv2.imwrite("res5.png",res) 
+0

그리드의 크기는 항상 픽셀 단위입니까? –

답변

0

사용 무릎 라인 감지 OpenCV Hough Transform에 대한 변환; 그것은 교합과 조명 변화에 강할 것이다. 아마도 수평선과 수직선이 같은 거리에 있다고 가정 할 수 있습니다. 따라서 수평선은 두 줄, 수직 방향은 두 줄만 감지하면됩니다.