前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >openCV 简单物体识别

openCV 简单物体识别

作者头像
用户6021899
发布2019-09-04 16:38:19
5.8K0
发布2019-09-04 16:38:19
举报
文章被收录于专栏:Python编程 pyqt matplotlib

本篇的例子介绍使用numpy和 OpenCV ,仅根据识别对象的尺寸和颜色进行简单的物体识别。专业的图像识别须借助机器学习(含神经网络即深度学习),本篇不做介绍。

下图截屏于支付宝登山赛小游戏,我们的任务是识别一系列截图中的小鸡和金币,并给出其各自中心位置的大概坐标(原点在图像的左上角)。

首先是抠掉不动的背景。上篇已有介绍,不再赘述。

接着将图像上部小鸡和金币不可能去的位置像素置零。

代码语言:javascript
复制
img[0: int(0.38*H),:, :] =0 #上边部分没有待检测目标,不参与计算, 置零

再分离通道:

代码语言:javascript
复制
B,G,R = cv2.split(img) # 分离三个颜色通道
#cv2.imshow("B", cv2.resize(B ,(int(0.3*W),int(0.3*H))))
#cv2.imshow("G", cv2.resize(G ,(int(0.3*W),int(0.3*H))))
#cv2.imshow("R", cv2.resize(R ,(int(0.3*W),int(0.3*H))))

然后分离小鸡等白色的部分:

小鸡的红色分量和蓝色分量都很亮。我们将图片红色通道稍暗的部分对应的蓝色通道置零,即分离出来了包含小鸡的白色部分。

代码语言:javascript
复制
B_ = B.copy() #深拷贝,防止串扰
B_[np.where(R<240)] =0 #红色通道稍暗的像素在蓝色通道置零
cv2.imshow("B_0", cv2.resize(B_ ,(int(0.3*W),int(0.3*H))))

然后转二值图,蓝色通道亮度小的部分置零以降噪。

代码语言:javascript
复制
B_ = np.where(B_<230,0,255).astype(np.uint8)  #亮度小的置零
cv2.imshow("B_", cv2.resize(B_ ,(int(0.3*W),int(0.3*H))))

有了二值图,我们就可以对其进行轮廓检测,加以尺寸限制,在原始图上画出矩形框。这些命令我写在函数drawRect()中:

代码语言:javascript
复制
#画矩形框且标记文本
def drawRect(src, dst, minW, minH, text='',maxW=np.inf, maxH= np.inf, RectColor=(0,0,255 ), textColor=(255,0,0)):
    contours, hierarchy = cv2.findContours(src, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    if contours is not None:
        for c in contours: #对于每一个轮廓
            x, y, w, h = cv2.boundingRect(c) #矩形框
            if minW<w and w< maxW and minH<h and h<maxH:  #按宽、高的大小过滤
                print(w,h)
                cv2.rectangle(dst, (x,y), (x+w, y+h), RectColor, 4) # 颜色均为(B,G,R)模式
                #putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]])
                cv2.putText(dst,text,(x+int(0.2*w),y+int(0.5*h)), cv2.FONT_HERSHEY_COMPLEX, 1, textColor, 2, 4,False)
                print("{text} 坐标:{x}, {y}".format(text =text, x=x+int(0.5*w), y= y+int(0.5*h)))
               
drawRect(B_, img1st, 0.12*W, 0.05*H, text='chick')#识别小鸡

金币识别的方法也相似:

代码语言:javascript
复制
#金币在红色通道最明显
#cv2.imshow("B", cv2.resize(B ,(int(0.3*W),int(0.3*H))))
R_ = R.copy()#深拷贝,防止串扰
R_[np.where(B>150)] =0 #蓝色通道稍亮的 在红色通道置零
cv2.imshow("R_0", cv2.resize(R_ ,(int(0.3*W),int(0.3*H))))
R_ = np.where(R_<200,0,255).astype(np.uint8) #亮度小的置零
#cv2.imshow("R_", cv2.resize(R_ ,(int(0.3*W),int(0.3*H))))
drawRect(R_, img1st, W/200.0, H/60.0, 'gold',H/28.0, H/28.0) #识别金币

最后,我们就得到了识别的结果:

代码语言:javascript
复制
cv2.imshow("detection", cv2.resize(img1st ,(int(0.3*W),int(0.3*H))))
cv2.waitKey()
cv2.destroyAllWindows()

小鸡和分数圈混到一起,有些瑕疵,需引入更细致的条件加以区分。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python可视化编程机器学习OpenCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档