赞
踩
先叠个甲(作者寒假才开始自学opencv,做题练手,还不是很熟练,如果有不正确或者有更好的方法,欢迎在评论区指出)
题目:从网上寻找任一魔方图片,识别其中白色色块,描绘并输出其中所有白色色块的中心点坐标(也可选择其他颜色,代码有变化,后续指出)
首先我们要知道大致的流程有哪些,本文章以识别白色块为例,以下是重点步骤:
后面也有完整代码
成功读取魔方图片
- # 读入图片,还可以将其
- import cv2 as cv
- import numpy as np
- img = cv.imread('./test1.jpg')
获取白色部分,并输出它的二值图:
这里我使用的是cv.inRange()函数,cv2.inRange 的作用是根据阈值进行二值化:阈值内的像素设置为白色 (255),阈值外的设置为黑色 (0) mask = cv2.inRange(hsv, lower, upper), 通过这个性质,设置阈值使白色以外的区域变黑。但使用时需要用HSV图像,所以要提前转换,通过HSV=cv.cvtColor(img,cv.COLOR_BGR2HSV)。
这里推荐:
【youcans 的 OpenCV 例程300篇】209. HSV 颜色空间的彩色图像分割 这个博主有详细介绍,不过我们知道阈值就行,图片也是截取该文章
- #最低阈值 lowercolor = np.array([Hmin, Smin, Vmin])
- #最高阈值 uppercolor = np.array([Hmax, Smax, Vmax])
- # 根据要保留的颜色设置阈值。该阈值内的像素会变成白色,其余为黑色
-
- HSV=cv.cvtColor(img,cv.COLOR_BGR2HSV) #转换图像
- lowerColor = np.array([0,0,211]) #设置最低阈值
- upperColor = np.array([180,30,255]) #设置最高阈值
-
- # 因为要保留的就是白色区域,因此根据白色阈值填入
(1)使用inRange函数,传入设置好的lowercolor和uppercolor
- 提取白色部分(指定区域变白,其他变黑)
- binary = cv.inRange(HSV, lowerColor,upperColor)
(2)得到的图像还是有很多残缺的地方,因此需要选择合适的方法去噪声,让图像更好看,这里我选择的是中值滤波。使用完后显示图片。
- # 运用中值滤波去除噪声
- median = cv.medianBlur(binary, 9)
- # 显示二值图
- cv_show('median',median) # 这里是我自己写的cv_show()函数,函数声明可放开头
-
- # def cv_show(name, img):
- #cv.imshow('name', img)
- #cv.waitKey(0)
- #cv.destroyAllWindows()
(3)结果:
将白色方块的轮廓在原图显示
这里使用轮廓检测cv2.findContours()的方法,并且返回contours轮廓信息,以及hierachy层级(这里用不到)。再将轮廓信息contours传入cv2.drawContours()在原图画出。我们可以使其显示。
- contours, hierachy = cv.findContours(median, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)
- #后两个为轮廓检索模式和轮廓逼近模式
-
- res = cv.drawContours(img, contours, -1,(0,0,255), 4)
- cv_show('res', res)
结果:
在原图中描绘物体中心点并输出坐标
运用了cv2.minEnclosingCircle(cnt)函数得中心点,cv2.circle()标出圆心。
这里可以把中心的点理解为半径特别小的圆因此就可以用cv.circle()函数
- # 4、原图白色中心点
- L = len(contours) # contours轮廓数据是数组,因此用len()测数组长度,为了循环画点使用
-
- for i in range(L):
- cnt = contours[i] # cnt表示第i个白色快的轮廓信息
- (x,y), radius = cv.minEnclosingCircle(cnt) # 得到白色块外接圆的圆心坐标和半径
- center = (int(x),int(y)) # 画center圆心时。x,y必须是整数
-
- # 标出中心点
- img2 = cv.circle(img, center,3,(0,0,255),5) # 传入圆心信息,并画在原图上
-
- print(center) # 输出各个中心点
-
- # 显示有中心点的图像
- cv_show("frame",img2) # 展示花了中心点的魔方图
结果:
到此,题目全部完成。
完整代码:
- import cv2 as cv
- import numpy as np
-
- # 写一个显示函数
- def cv_show(name, img):
- cv.imshow(name, img)
- cv.waitKey(0)
- cv.destroyAllWindows()
-
- # 1、读取图片并显示
- img = cv.imread('./test1.jpg')
- cv_show('img', img)
-
- # 2、输出白色色块的二值图并显示
- # 转化为HSV进行处理
- HSV=cv.cvtColor(img,cv.COLOR_BGR2HSV)
- lowerColor = np.array([0,0,211])
- upperColor = np.array([180,30,255])
-
- # 提取白色部分(指定区域变白,其他变黑)
- binary = cv.inRange(HSV, lowerColor,upperColor)
-
- # 运用中值滤波去除噪声
- median = cv.medianBlur(binary, 9)
-
- # 显示二值图
- cv_show('median',median)
-
- # 3、得到轮廓,并在原图输出
- contours, hierachy = cv.findContours(median, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)
- res = cv.drawContours(img, contours, -1,(0,0,255), 4)
- cv_show('res', res)
-
- # 4、原图白色中心点
- L = len(contours) # contours轮廓数据是数组,因此用len()测数组长度,为了循环画点使用
- print("coordinate:")
- for i in range(L):
- cnt = contours[i] # cnt表示第i个白色快的轮廓信息
- (x,y), radius = cv2.minEnclosingCircle(cnt) # 得到白色块外接圆的圆心坐标和半径
- center = (int(x),int(y)) # 画center圆心时。x,y必须是整数
-
- # 标出中心点
- img2 = cv2.circle(img, center,3,(0,0,255),5) # 传入圆心信息,并画在原图上
-
- print(center) # 输出各个中心点
-
- # 显示有中心点的图像
- cv_show("img2",img2) # 展示花了中心点的魔方图
“向着月亮出发,即使不能到达,也能站在群星之中”
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。