zl程序教程

您现在的位置是:首页 >  Java

当前栏目

基于SimpleBlobDetector识别骰子点数

2023-02-18 16:38:50 时间

什么是Blob?

Blob是图像中一组相连的像素,它们具有一些共同的属性(例如灰度值),Blob检测的目的是识别并标记这些区域。OpenCV提供了一种方便的方法来检测blob并可以根据不同特征对其进行过滤,它就是SimpleBlobDetector,让我们看一个简单的例子:

上图中有6个骰子,我们希望自动识别骰子的点数,步骤:

① 自适应阈值二值化凸显骰子外轮廓

② 轮廓查找过滤截取每个骰子ROI

③ 使用SimpleBlobDetector检测ROI中的圆,计算点数输出

下面是代码和效果:

import cv2
# putText函数使用的字体定义
font = cv2.FONT_HERSHEY_SIMPLEX
 
# 读取图片、灰度转换、自适应阈值
img = cv2.imread("A.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                            cv2.THRESH_BINARY_INV,15,3)
# 查看二值化结果
cv2.imshow("thres", thresh)
# 轮廓查找
contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# 设置SimpleBlobDetector参数
params = cv2.SimpleBlobDetector_Params()

# 通过圆率来过滤>0.7
params.filterByCircularity = True
params.minCircularity = 0.7

# 应用参数
detector = cv2.SimpleBlobDetector_create(params)

# 变量轮廓通过外界矩形宽截取每个骰子ROI
for cnt in contours:
  (x, y, w, h) = cv2.boundingRect(cnt)
  if w > 100 and h > 100:
    cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
    roi = gray[y:y+h, x:x+w]
    cv2.imshow("roi",roi)
    cv2.waitKey(0)
    # 圆形Blob检测
    keypoints = detector.detect(roi)
    # len(keypoints)就是检测到的圆形Blob数量
    print(len(keypoints))
    cv2.putText(img, str(len(keypoints)), (x+15, y+25), font, 1.0, (0, 0, 255), 2)

# 显示结果
cv2.imshow("result", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

当然这是个简单的实例,点数计数也可以用轮廓删选的方法代替,比如大小,宽高比等,本质上和SimpleBlobDetector是类似的,它还可以设置其他参数进行Blob过滤,比如:

具体可以参考这篇文章:https://www.learnopencv.com/blob-detection-using-opencv-python-c/

对于骰子识别,传统算法一般需要分割,然后识别,识别还可以用模板匹配的方法,不妨一试,另外如果你用深度学习的方法,那就多收集标注一些数据,检测就可以一步到位了,比如这种效果: