1

我正在尝试找到带有圆圈/十字的网格元素或里面填充的东西。我使用这里的代码来构建我的逻辑。

逻辑 - 查找网格坐标 -> 使用每个矩形块的左上角和右下角坐标提取网格元素的子图像 -> 查找非零像素的数量 -> 如果矩形填充超过 50%,则将其视为已填充

如果网格为空,我能够成功找到所有网格坐标。但是,如果填充了任何网格元素,则从图像中可以看出,事情不会按预期工作。如何修复此代码以每次成功确定所有网格坐标?

图像.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)
4

1 回答 1

0

使用霍夫变换进行线检测OpenCV 霍​​夫变换;它将对遮挡和光照变化具有鲁棒性。也许您还可以假设水平线和垂直线是等距的,因此您只需要检测两条用于水平方向的线和两条用于垂直方向的线。

于 2014-04-11T07:22:00.077 回答