更新时间:2022-10-19 13:12:45
这是一种方法
使用 cv2.filter2D( )
。我们使用通用的锐化内核,可以在
现在获得二进制图像的阈值
执行形态学操作
从这里我们找到轮廓并使用 cv2.contourArea()$进行过滤c $ c>具有最小/最大阈值区域。
我们可以使用Numpy裁剪每个所需的正方形区域像这样切片并保存每个ROI
x,y,w,h = cv2.boundingRect(c)
ROI = image [y:y + h,x:x + h]
cv2.imwrite('ROI _ {}。png'.format(image_number),ROI)
导入cv2
将numpy导入为np
image = cv2.imread('1.png')
grey = cv2.cvtColor(image,cv2。 COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray,5)
sharpen_kernel = np.array([[-1,-1,-1],[-1,9,-1],[- 1,-1,-1]])
sharpen = cv2.filter2D(blur,-1,sharpen_kernel)
thresh = cv2.threshold(sharpen,160,255,cv2.THRESH_BINARY_INV)[ 1]
内核= cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
close = cv2.morphologyEx(阈值,cv2.MORPH_CLOSE,内核,迭代次数= 2)
cnts = cv2 .findContours(close,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts [0]如果len(cnts)== 2 else cnts [1]
min_area = 100
max_area = 1500
image_number = 0
(单位为c):
area = cv2.contourArea(c)
如果area> min_area和area< max_area:
x,y,w,h = cv2.boundingRect(c)
ROI = image [y:y + h,x:x + h]
cv2.imwrite('ROI_ { } .png'.format(image_number),ROI)
cv2.rectangle(image,(x,y),(x + w,y + h),(36,255,12),2)
image_number + = 1
cv2.imshow('sharpen',锐化)
cv2.imshow('close',close)
cv2.imshow('thresh',thresh)
cv2.imshow('image',image)
cv2.waitKey()
I am trying to detect all the squared shaped dice images so that i can crop them individually and use that for OCR. Below is the Original image:
Here is the code i have got but it is missing some squares.
def find_squares(img):
img = cv2.GaussianBlur(img, (5, 5), 0)
squares = []
for gray in cv2.split(img):
for thrs in range(0, 255, 26):
if thrs == 0:
bin = cv2.Canny(gray, 0, 50, apertureSize=5)
bin = cv2.dilate(bin, None)
else:
_retval, bin = cv2.threshold(gray, thrs, 255, cv2.THRESH_BINARY)
bin, contours, _hierarchy = cv2.findContours(bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
cnt_len = cv2.arcLength(cnt, True)
cnt = cv2.approxPolyDP(cnt, 0.02*cnt_len, True)
if len(cnt) == 4 and cv2.contourArea(cnt) > 1000 and cv2.isContourConvex(cnt):
cnt = cnt.reshape(-1, 2)
max_cos = np.max([angle_cos( cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4] ) for i in range(4)])
#print(cnt)
a = (cnt[1][1] - cnt[0][1])
if max_cos < 0.1 and a < img.shape[0]*0.8:
squares.append(cnt)
return squares
dice = cv2.imread('img1.png')
squares = find_squares(dice)
cv2.drawContours(dice, squares, -1, (0, 255, 0), 3)
Here are the Output images:
As per my analysis, some squares are missing due to missing canny edges along the dice because of smooth intensity transition between dice and background.
Given the constraint that there will always be 25 dices in square grid pattern (5*5) can we predict the missing square positions based on recognised squares? Or can we modify above algorithm for square detection algorithm?
Here's an approach
Sharpen image with cv2.filter2D()
. We use a generic sharpen kernel, other kernels can be found here
Now threshold to get a binary image
Perform morphological operations
From here we find contours and filter using cv2.contourArea()
with minimum/maximum threshold areas.
We can crop each desired square region using Numpy slicing and save each ROI like this
x,y,w,h = cv2.boundingRect(c)
ROI = image[y:y+h, x:x+h]
cv2.imwrite('ROI_{}.png'.format(image_number), ROI)
import cv2
import numpy as np
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray, 5)
sharpen_kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
sharpen = cv2.filter2D(blur, -1, sharpen_kernel)
thresh = cv2.threshold(sharpen,160,255, cv2.THRESH_BINARY_INV)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
min_area = 100
max_area = 1500
image_number = 0
for c in cnts:
area = cv2.contourArea(c)
if area > min_area and area < max_area:
x,y,w,h = cv2.boundingRect(c)
ROI = image[y:y+h, x:x+h]
cv2.imwrite('ROI_{}.png'.format(image_number), ROI)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
image_number += 1
cv2.imshow('sharpen', sharpen)
cv2.imshow('close', close)
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()