摘要:它们的补色是黄色为,青色为紫色为饱和度饱和度表示颜色接近光谱色的程度。光谱色的白光成分为,饱和度达到最高。转换图像格式得到滑动条的数值参数第一个参数是滑动条名字,第二个时所在窗口,返回值是滑动条的数值。
学习颜色识别之前先介绍一下新认识的图像格式HSV:
用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,紫色为300°;
饱和度S表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。
明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。
注意:H: 0 — 180;S: 0 — 255;V: 0 — 255。
那么为什么不直接用RGB格式呢?
由于数字图像中物体颜色的R、G和B分量都与照射到物体上的光量相关,因此相互关联,因此根据这些分量的图像描述使得物体识别困难。色调/明度/色度或色调/明度/饱和度方面的描述通常更相关。
在识别前要对图像做一系列预处理:
将原图像进行模糊处理,方便颜色的提取
img1 = cv2.GaussianBlur(src,ksize,sigmaX,sigmay,borderType)#src: 输入图像#ksize:高斯卷积核的大小,注意 : 卷积核的宽度和高度都应为奇数,且可以不同#sigmaX: 水平方向的标准差#sigmaY: 垂直方向的标准差,默认值为0,表示与sigmaX相同#borderType:填充边界类型
cv2.cvtColor(图像对象, cv2.COLOR_之前图像格式2要转换成的图像格式)#第二个参数的意思就是在被转换格式和预转换格式之间加一个‘2’#比方RGB转HSV === cv2.COLOR_RGB2HSV#这里列举一下基本的图片格式#BGR#RGB#GRAY#HSV#YCRCb#HLS#XYZ#LAB#YUV
基本上是腐蚀、膨胀、开闭运算的运用,具体要看环境情况,可以参考Day3博客里介绍的各种方法的优缺点来抉择用上门处理方法
树莓派 Opencv-基于Python学习记录DAY-3 形态学处理-腐蚀、膨胀、开闭运算_凉山有客不自赏的博客-CSDN博客
cv2.inRange(hsv, lower_, upper_)#处理对象,阈值上限,阈值下限
这一步就是对单一颜色的识别,将目标颜色的颜色转换为白色,其他背景转换为黑色
关于颜色阈值的获取可以使用以下代码,通过导入图片,拖动滑块获取阈值
import cv2import numpy as npdef nothing(x): pass cv2.namedWindow("Tracking")cv2.createTrackbar("LH","Tracking",35,255,nothing)cv2.createTrackbar("LS","Tracking",43,255,nothing)cv2.createTrackbar("LV","Tracking",46,255,nothing)cv2.createTrackbar("UH","Tracking",77,255,nothing)cv2.createTrackbar("US","Tracking",255,255,nothing)cv2.createTrackbar("UV","Tracking",255,255,nothing)#cv2.createTrackbar:绑定滑动条和窗口,定义滚动条的数值#参数#第一个参数时滑动条的名字,#第二个参数是滑动条被放置的窗口的名字,#第三个参数是滑动条默认值,#第四个参数时滑动条的最大值,#第五个参数时回调函数,每次滑动都会调用回调函数。while True: frame = cv2.imread("1.jpeg") hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) #转换图像格式 l_h = cv2.getTrackbarPos("LH","Tracking") l_s = cv2.getTrackbarPos("LS","Tracking") l_v = cv2.getTrackbarPos("LV","Tracking") u_h = cv2.getTrackbarPos("UH","Tracking") u_s = cv2.getTrackbarPos("US","Tracking") u_v = cv2.getTrackbarPos("UV","Tracking") #cv2.getTrackbarPos:得到滑动条的数值 #参数 #第一个参数是滑动条名字, #第二个时所在窗口, #返回值是滑动条的数值。 l_g = np.array([l_h, l_s, l_v]) # 阈值下限 u_g = np.array([u_h,u_s,u_v]) # 阈值上限 mask = cv2.inRange(hsv,l_g,u_g) # 二值化 res=cv2.bitwise_and(frame,frame,mask=mask) #cv2.bitwise_and是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,将原图与二值化图像与运算,将阈值内的颜色以原本颜色显示 cv2.imshow("frame", frame) cv2.imshow("mask", mask) cv2.imshow("res", res) #显示窗口 key = cv2.waitKey(1) if key == 27: break cv2.destroyAllWindows()#延时,当按下ESC时关闭窗口,如果用户没有按下键,则继续等待下一个delay时间(循环),直到用户按键触发
效果展示:
import cv2import numpy as npball_color = "green"color_dist = {"red": {"Lower": np.array([0, 60, 60]), "Upper": np.array([6, 255, 255])}, "blue": {"Lower": np.array([100, 80, 46]), "Upper": np.array([124, 255, 255])}, "green": {"Lower": np.array([35, 43, 35]), "Upper": np.array([90, 255, 255])}, }cap = cv2.VideoCapture(0)cv2.namedWindow("camera", cv2.WINDOW_AUTOSIZE)while cap.isOpened(): ret, frame = cap.read() if ret: if frame is not None: gs_frame = cv2.GaussianBlur(frame, (5, 5), 0) # 高斯模糊 hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV) # 转化成HSV图像 erode_hsv = cv2.erode(hsv, None, iterations=2) # 腐蚀 粗的变细 inRange_hsv = cv2.inRange(erode_hsv, color_dist[ball_color]["Lower"], color_dist[ball_color]["Upper"]) cv2.imshow("camera", inRange_hsv) cv2.waitKey(1) else: print("无画面") else: print("无法读取摄像头!")cap.release()cv2.waitKey(0)cv2.destroyAllWindows()
主要使用cv2.findContours()函数来查找检测物体的轮廓。前提是对二值化的图片检测。
contours, hierarchy=cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]]) #第一个参数是寻找轮廓的图像;#第二个参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):# cv2.RETR_EXTERNAL 表示只检测外轮廓# cv2.RETR_LIST 检测的轮廓不建立等级关系# cv2.RETR_CCOMP 建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息.#如果内孔内还有一个连通物体,这个物体的边界也在顶层。# cv2.RETR_TREE 建立一个等级树结构的轮廓。#第三个参数method为轮廓的近似办法# cv2.CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-#x2),abs(y2-y1))==1# cv2.CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例#如一个矩形轮廓只需4个点来保存轮廓信息# cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS 使用teh-Chinl chain 近似算法#返回值#cv2.findContours()函数返回两个值,一个是轮廓本身contour,还有一个是每条轮廓对应的属性hierarchy。#contour返回一个list,list中每个元素都是图像中的一个轮廓,用numpy中的ndarray表示。#hierarchy返回一个可选的hiararchy结果,这是一个ndarray,其中的元素个数和轮廓个数相同,每个轮廓#contours[i]对应4个hierarchy元素hierarchy[i][0] ~hierarchy[i][3],分别表示后一个轮廓、前一个轮#廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,则该值为负数
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]]) #第一个参数是指明在哪幅图像上绘制轮廓;#第二个参数是轮廓本身,在Python中是一个list。#第三个参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。#后面的参数很简单。其中thickness表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。绘制参数将在以后独立详细介绍。
示例代码
import cv2 img = cv2.imread("./example.png") gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)cv2.drawContours(img,contours,-1,(0,0,255),3) cv2.imshow("img", img) cv2.waitKey(0)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/121262.html
摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...
摘要:但是如果你和我是一样的人,你想自己攒一台奇快无比的深度学习的电脑。可能对深度学习最重要的指标就是显卡的显存大小。性能不错,不过够贵,都要美元以上,哪怕是旧一点的版本。电源我花了美元买了一个的电源。也可以安装,这是一个不同的深度学习框架。 是的,你可以在一个39美元的树莓派板子上运行TensorFlow,你也可以在用一个装配了GPU的亚马逊EC2的节点上跑TensorFlow,价格是每小时1美...
摘要:而深度学习的手写数字识别去年被官方下架了。。。深度学习方法改成旧版本,用自己的深度学习。神经网络训练树莓派之前做过这个,还比较有底,但是要自己标千多张数据集。 20...
摘要:同时我还添加了语音播报的功能,而且还能将开门信息推送到微信上,这样就可以试试的看到有谁来开门了。 继最基础的IO口控制的学习,现在我来回顾我想要做的,嗯..我想要做一个基于opencv和树莓派的一个人脸识别的门禁,现在人脸识别有了,io控制大概清楚了..现在问题就是,如何通过人脸识别成功来控...
阅读 3387·2021-10-13 09:40
阅读 2924·2021-10-09 09:53
阅读 3140·2021-09-27 13:35
阅读 3305·2021-09-26 09:46
阅读 1676·2021-09-08 09:36
阅读 4016·2021-09-02 09:46
阅读 1054·2019-08-30 15:54
阅读 2961·2019-08-30 15:44