ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用Opencv实现魔方识别(一):边缘及位置识别

2019-08-03 20:36:17  阅读:1081  来源: 互联网

标签:center Opencv image 魔方 cv2 边缘 识别 contour


之前做魔方机器人,使用的是人工输入默认的各个表面方块颜色分布,不够方便与智能,因此开始研究使用摄像头识别魔方。Opencv基本是首选而且方便简单的工具。本文将描述如何使用Opencv识别从摄像头抓取的魔方图片内魔方的各个方块边缘以及位置,用于后续的颜色的识别。

安装opencv

Pycharm支持从界面选择安装python包,在文件菜单下选择设置项,然后如下图找到安装界面:
在这里插入图片描述
需要用到的安装包列表:numpy,Matplotlib,opencv-python

边缘检测

从摄像头抓取的原图如下:
在这里插入图片描述

灰化去除颜色信息

代码:

import cv2
import numpy as np
from copy import deepcopy
import math

imgobj = cv2.imread('1.jpg')
gray = cv2.cvtColor(imgobj, cv2.COLOR_BGR2GRAY)
cv2.namedWindow("image")
cv2.imshow("image", gray)
cv2.waitKey(0)

效果如下:
在这里插入图片描述

高斯模糊扩大边缘效果

代码:

blurred = cv2.GaussianBlur(gray, (3, 3), 0)
cv2.imshow("image", blurred)
cv2.waitKey(0)

效果如下:
在这里插入图片描述

Canny算法实现边缘检测

Canny边缘检测是一种非常流行的边缘检测算法,是John Canny在1986年提出的。具体可以参考:
https://en.wikipedia.org/wiki/Canny_edge_detector

代码:

canny = cv2.Canny(blurred, 20, 40)
cv2.imshow("image", canny)
cv2.waitKey(0)

效果如下:
在这里插入图片描述

边缘线膨胀化

canny检测的边缘线很细,使得同一边缘有多个边缘线,这里可以用opencv dilate函数,使边缘线膨胀化,这样同一边缘的多个边缘线即可合并成同一条线。

代码:

kernel = np.ones((3,3), np.uint8)
dilated = cv2.dilate(canny, kernel, iterations=2)
cv2.imshow("image", blurred)
cv2.waitKey(0)

效果如下:
在这里插入图片描述

去除多余边缘

膨胀化后,可以看到很多魔方外的物体边缘,以及魔方内的小边缘,这些都需要去除。通过计算闭合边缘的面积以及中心点的位置,可以判断出哪些是魔方的边缘,哪些是多余的边缘。
在计算面积与中心点时,需要对闭合边缘使用approxPolyDP函数进行多变拟合。findContours为遍历提取所有的闭合区域,arcLength为计算闭合区域的周长,contourArea计算闭合区域的面积。
代码:

(contours, hierarchy) = cv2.findContours(dilated.copy(),
                                         cv2.RETR_TREE,
                                         cv2.CHAIN_APPROX_SIMPLE)


candidates = []
hierarchy = hierarchy[0]

index = 0
pre_cX = 0
pre_cY = 0
center = []
for component in zip(contours, hierarchy):
    contour = component[0]
    peri = cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, 0.1 * peri, True)
    area = cv2.contourArea(contour)
    corners = len(approx)

    # compute the center of the contour
    M = cv2.moments(contour)

    if M["m00"]:
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])
    else:
        cX = None
        cY = None

    if 14000 < area < 20000 and cX is not None:
        tmp = {'index': index, 'cx': cX, 'cy': cY, 'contour': contour}
        center.append(tmp)
        index += 1

center.sort(key=lambda k: (k.get('cy', 0)))
row1 = center[0:3]
row1.sort(key=lambda k: (k.get('cx', 0)))
row2 = center[3:6]
row2.sort(key=lambda k: (k.get('cx', 0)))
row3 = center[6:9]
row3.sort(key=lambda k: (k.get('cx', 0)))

center.clear()
center = row1 + row2 + row3

for component in center:
    candidates.append(component.get('contour'))

cv2.drawContours(imgobj, candidates, -1, (0, 0, 255), 3)
cv2.imshow("image", imgobj)
cv2.waitKey(0)

效果如下:
在这里插入图片描述
通过效果图,对于魔方的边缘及位置识别基本正确,后续即可对识别区域内的颜色进行分析,会在后续文章中进行。

标签:center,Opencv,image,魔方,cv2,边缘,识别,contour
来源: https://blog.csdn.net/u010841775/article/details/98367173

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有