当前位置:   article > 正文

opencv-python识别魔方特定颜色方块,并输出各方块中心坐标_opencv识别物体并输出坐标点

opencv识别物体并输出坐标点

先叠个甲(作者寒假才开始自学opencv,做题练手,还不是很熟练,如果有不正确或者有更好的方法,欢迎在评论区指出)

题目从网上寻找任一魔方图片,识别其中白色色块,描绘并输出其中所有白色色块的中心点坐标(也可选择其他颜色,代码有变化,后续指出)


首先我们要知道大致的流程有哪些,本文章以识别白色块为例,以下是重点步骤:

后面也有完整代码

  1. 成功读取魔方图片

  1. # 读入图片,还可以将其
  2. import cv2 as cv
  3. import numpy as np
  4. img = cv.imread('./test1.jpg')

  1. 获取白色部分,并输出它的二值图:

这里我使用的是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 颜色空间的彩色图像分割 这个博主有详细介绍,不过我们知道阈值就行,图片也是截取该文章

  1. #最低阈值 lowercolor = np.array([Hmin, Smin, Vmin])
  2. #最高阈值 uppercolor = np.array([Hmax, Smax, Vmax])
  3. # 根据要保留的颜色设置阈值。该阈值内的像素会变成白色,其余为黑色
  4. HSV=cv.cvtColor(img,cv.COLOR_BGR2HSV) #转换图像
  5. lowerColor = np.array([0,0,211])        #设置最低阈值
  6. upperColor = np.array([180,30,255])     #设置最高阈值
  7. # 因为要保留的就是白色区域,因此根据白色阈值填入

(1)使用inRange函数,传入设置好的lowercolor和uppercolor

  1. 提取白色部分(指定区域变白,其他变黑)
  2. binary = cv.inRange(HSV, lowerColor,upperColor)

(2)得到的图像还是有很多残缺的地方,因此需要选择合适的方法去噪声,让图像更好看,这里我选择的是中值滤波。使用完后显示图片。

  1. # 运用中值滤波去除噪声
  2. median = cv.medianBlur(binary, 9)
  3. # 显示二值图
  4. cv_show('median',median) # 这里是我自己写的cv_show()函数,函数声明可放开头
  5. # def cv_show(name, img):
  6. #cv.imshow('name', img)
  7. #cv.waitKey(0)
  8. #cv.destroyAllWindows()

(3)结果:

  1. 将白色方块的轮廓在原图显示

这里使用轮廓检测cv2.findContours()的方法,并且返回contours轮廓信息,以及hierachy层级(这里用不到)。再将轮廓信息contours传入cv2.drawContours()在原图画出。我们可以使其显示。

  1. contours, hierachy = cv.findContours(median, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)
  2. #后两个为轮廓检索模式和轮廓逼近模式
  3. res = cv.drawContours(img, contours, -1,(0,0,255), 4)
  4. cv_show('res', res)

结果:

  1. 在原图中描绘物体中心点并输出坐标

运用了cv2.minEnclosingCircle(cnt)函数得中心点,cv2.circle()标出圆心。

这里可以把中心的点理解为半径特别小的圆因此就可以用cv.circle()函数

  1. # 4、原图白色中心点
  2. L = len(contours) # contours轮廓数据是数组,因此用len()测数组长度,为了循环画点使用
  3. for i in range(L):
  4. cnt = contours[i]    # cnt表示第i个白色快的轮廓信息
  5. (x,y), radius = cv.minEnclosingCircle(cnt) # 得到白色块外接圆的圆心坐标和半径
  6. center = (int(x),int(y)) # 画center圆心时。x,y必须是整数
  7. # 标出中心点
  8. img2 = cv.circle(img, center,3,(0,0,255),5) # 传入圆心信息,并画在原图上
  9. print(center) # 输出各个中心点
  10. # 显示有中心点的图像
  11. cv_show("frame",img2)    # 展示花了中心点的魔方图

结果:

到此,题目全部完成。


完整代码:

  1. import cv2 as cv
  2. import numpy as np
  3. # 写一个显示函数
  4. def cv_show(name, img):
  5. cv.imshow(name, img)
  6. cv.waitKey(0)
  7. cv.destroyAllWindows()
  8. # 1、读取图片并显示
  9. img = cv.imread('./test1.jpg')
  10. cv_show('img', img)
  11. # 2、输出白色色块的二值图并显示
  12. # 转化为HSV进行处理
  13. HSV=cv.cvtColor(img,cv.COLOR_BGR2HSV)
  14. lowerColor = np.array([0,0,211])
  15. upperColor = np.array([180,30,255])
  16. # 提取白色部分(指定区域变白,其他变黑)
  17. binary = cv.inRange(HSV, lowerColor,upperColor)
  18. # 运用中值滤波去除噪声
  19. median = cv.medianBlur(binary, 9)
  20. # 显示二值图
  21. cv_show('median',median)
  22. # 3、得到轮廓,并在原图输出
  23. contours, hierachy = cv.findContours(median, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)
  24. res = cv.drawContours(img, contours, -1,(0,0,255), 4)
  25. cv_show('res', res)
  26. # 4、原图白色中心点
  27. L = len(contours)    # contours轮廓数据是数组,因此用len()测数组长度,为了循环画点使用
  28. print("coordinate:")
  29. for i in range(L):
  30. cnt = contours[i]    # cnt表示第i个白色快的轮廓信息
  31. (x,y), radius = cv2.minEnclosingCircle(cnt) # 得到白色块外接圆的圆心坐标和半径
  32. center = (int(x),int(y)) # 画center圆心时。x,y必须是整数
  33. # 标出中心点
  34. img2 = cv2.circle(img, center,3,(0,0,255),5) # 传入圆心信息,并画在原图上
  35. print(center) # 输出各个中心点
  36. # 显示有中心点的图像
  37. cv_show("img2",img2) # 展示花了中心点的魔方图

“向着月亮出发,即使不能到达,也能站在群星之中”

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/369929
推荐阅读
相关标签
  

闽ICP备14008679号