图像中的正方形检测 [英] Square detection in image

查看:248
本文介绍了图像中的正方形检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试检测所有方形骰子图像,以便我可以单独裁剪它们并将其用于OCR。
以下是原始图像:






这是我得到的代码,但缺少一些正方形。

  def find_squares (img):
img = cv2.GaussianBlur(img,(5,5),0)
squares = []
for cv2.split中的灰度(img):
对于范围(0、255、26)中的thrs:如果thrs == 0:

bin = cv2.Canny(灰色,0、50,apertureSize = 5)
bin = cv2。 dilate(bin,None)
else:
_retval,bin = cv2.threshold(gray,thrs,255,cv2.THRESH_BINARY)
bin,等高线,_hierarchy = cv2.findContours(bin, cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
用于轮廓中的cnt:
cnt_len = cv2.arcLength(cnt,True)
cnt = cv2.approxPolyDP(cnt,0.02 * cnt_len,True)
如果len(cnt)== 4并且cv2.contourArea(cnt)> 1000和cv2.isContourConvex(cnt):
cnt = cnt.reshape(-1,2)
max_cos = np.max([angle_cos(cnt [i],cnt [(i + 1)% 4],对于范围i中的i,cnt [(i + 2)%4])])
#print(cnt)
a =(cnt [1] [1]-cnt [0] [1])如果max_cos<

0.1且< img.shape [0] * 0.8:

squares.append(cnt)
返回正方形

dice = cv2.imread('img1.png')
squares = find_squares(dice)
cv2.drawContours(dice,squares,-1,(0,255,0),3)

以下是输出图像:



根据我的分析,由于骰子和背景之间的平滑强度过渡,由于缺少沿骰子的Canny边缘,因此缺少一些正方形。



鉴于正方形网格模式(5 * 5)中始终有25个骰子的约束,我们可以根据公认的正方形来预测丢失的正方形位置吗?
还是可以将上述算法修改为平方检测算法?

解决方案

这是一种方法




  • 将图像转换为灰度,将中值模糊转换为平滑图像

  • 锐化图像以增强边缘

  • 阈值

  • 进行形态转换

  • 使用最小/最大阈值区域查找轮廓并过滤

  • 裁剪并保存ROI






使用 cv2.filter2D( )。我们使用通用的锐化内核,可以在



现在获得二进制图像的阈值





执行形态学操作





从这里我们找到轮廓并使用 cv2.contourArea()具有最小/最大阈值区域。





我们可以使用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

  • Convert image to grayscale and median blur to smooth image
  • Sharpen image to enhance edges
  • Threshold
  • Perform morphological transformations
  • Find contours and filter using minimum/maximum threshold area
  • Crop and save ROI

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()

这篇关于图像中的正方形检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆