先叠个甲(作者寒假才开始自学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) # 展示花了中心点的魔方图
“向着群月亮出发,即使不能到达,也能站在群星之中”
版权归原作者 Delighted21 所有, 如有侵权,请联系我们删除。