1、实战项目(找中线)

目标是从面对这种简单环境用opencv画出中线,下面是过程实现

2、opencv-python基于HSV抠图

这种环境看似简单,但是用灰度处理二值化的效果奇差,最后选择用HSV进行分割。

先导入包:

import cv2
import cv2 as cv
import numpy as np

然后把图片用cvtColor转化成HSV格式

img=cv.imread("1.png")img=cv.cvtColor(img,cv.COLOR_BGR2HSV)

关于HSV :

HSV模型中颜色的参数分别是:色调(H),饱和度(S),明度(V)
色调H用角度度量,取值范围为0~360,从红色开始按逆时针方向计算,红色为0,绿色为120,蓝色为240,他们的补色是:
黄色为60,青色为180,紫色为300
如果直接使用opencv中cvtColor函数,并设置参数为CV_BGR2HSV,那么所得的HSV范围分别是【0,180】【0,255】【0,255】
lower=np.array([0,0,137])
upper=np.array([120,255,255])mask = cv2.inRange(img,lowerb=lower,upperb=upper)

关于cv2.inRange方法

mask = inRange(hsv,lower_red,upper_red)
hsv:原图
lower_red指的是图像中低于这个lower_red的值,图像值变为0
upper_red指的是图像中高于这个upper_red的值,图像值变为0

阈值的选择

阈值的选择比较烦人,上面的数值是匹配第一张图片分割的。下面提供一个可视化工具,帮助你找到合适的阈值。

import cv2
import numpy as np# 滑动条的回调函数,获取滑动条位置处的值
def empty(a):h_min = cv2.getTrackbarPos("Hue Min", "TrackBars")h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")v_min = cv2.getTrackbarPos("Val Min", "TrackBars")v_max = cv2.getTrackbarPos("Val Max", "TrackBars")print(h_min, h_max, s_min, s_max, v_min, v_max)return h_min, h_max, s_min, s_max, v_min, v_maxpath = '1.png'
# 创建一个窗口,放置6个滑动条
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars", 640, 240)
cv2.createTrackbar("Hue Min", "TrackBars", 0, 120, empty)
cv2.createTrackbar("Hue Max", "TrackBars", 19, 120, empty)
cv2.createTrackbar("Sat Min", "TrackBars", 110, 255, empty)
cv2.createTrackbar("Sat Max", "TrackBars", 240, 255, empty)
cv2.createTrackbar("Val Min", "TrackBars", 153, 255, empty)
cv2.createTrackbar("Val Max", "TrackBars", 255, 255, empty)while True:img = cv2.imread(path)imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)# 调用回调函数,获取滑动条的值h_min, h_max, s_min, s_max, v_min, v_max = empty(0)lower = np.array([h_min, s_min, v_min])upper = np.array([h_max, s_max, v_max])# 获得指定颜色范围内的掩码mask = cv2.inRange(imgHSV, lower, upper)# 对原图图像进行按位与的操作,掩码区域保留imgResult = cv2.bitwise_and(img, img, mask=mask)cv2.imshow("Mask", mask)cv2.imshow("Result", imgResult)cv2.waitKey(1)

边界轮廓线拟合 :

contours_,h_ = cv.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
mask = cv2.cvtColor(mask,cv2.COLOR_GRAY2BGR)
cv2.drawContours(mask,contours_,-1,(0,255,0),3)

这里拟合出边界轮廓线并且直接画出来,线的厚度可以在drawContours的最后一个参数3的地方修改。这里contours_的数据类型如下,如果有相关操作注意:

最后展示图片

cv2.imshow("result",mask)
cv2.waitKey(0)

轮廓拟合效果如下:

附上二值化效果:

3.拟合中线:

在网上找了多种直线拟合方法,如霍夫直线拟合骨架提取,opencv骨架提取,效果都不好,这里尝试用cv2.fitLine和cv2.line函数自己写一个中线提取方法。

middle_s=[]for i in range(0,480):count = 0sum=0for j in range(0,1103):if contours_[1][j][0][1] == i:sum+=contours_[1][j][0][0]count+=1middle=sum/countprint(count)middle_s.append([[middle,i]])contours_middle=np.array(middle_s).astype(np.int32)cv2.drawContours(mask,contours_middle,-1,(0,255,0),2)output=cv2.fitLine(contours_middle, cv2.DIST_L2, 0, 0.01, 0.01)
k = output[1] / output[0]
b = output[3] - k * output[2]
x_0=-b/k
x_480=(479-b)/k
cv.line(mask,(int(x_0),0),(int(x_480),479),(255,0,0),4)
cv.line(img_c,(int(x_0),0),(int(x_480),479),(255,0,0),4)cv.imshow("img_c",img_c)
cv.imshow("line",mask)
cv.imshow("mask",mask_c)
cv.waitKey(0)

代码中的img_c是上面代码copy的原图,mask是经过轮廓拟合的图片

关于fitLine及直线拟合算法:

fitLine的返回值output有四维,前面两个维度表示方向,类似方向向量两个相除就可以得到斜率k,后面两个维度是直线上一个点的横坐标和纵坐标。斜率k=output[1]/output[0]。有了斜率之后可以求得直线与上下边界线的焦点,直接用line()函数画出拟合的直线。

注意:

这里拟合的是直线,如果有拟合曲线中线需求的可以尝试使用两端轮廓线均值的方法,或者其他函数方法。这里的代码是仅仅适用于第一个图那种单直到的直线拟合,如果是复杂场景可以自己调整。

完整代码如下:

#导入包
import cv2
import cv2 as cv
import numpy as np#导入图片并备份
img=cv.imread("1.png")
img_c=img.copy()
#把图片转换成HSV颜色空间
img=cv.cvtColor(img,cv.COLOR_BGR2HSV)#创建二值化阈值的上下界数组
lower=np.array([0,0,137])
upper=np.array([120,255,255])
#进行inRange()二值化
mask = cv2.inRange(img,lowerb=lower,upperb=upper)mask_c=mask.copy()#备份图片#拟合轮廓线,这种方法找的轮廓线不太干净,可以使用Canny会好一点,但是对于中线拟合影响不大
contours_,h_ = cv.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
mask = cv2.cvtColor(mask,cv2.COLOR_GRAY2BGR)
cv2.drawContours(mask,contours_,-1,(0,255,0),3)
mask_line=mask.copy()#备份轮廓线图片#创建中线点集
middle_s=[]#利用循环将中线的点填充到点集中
for i in range(0,480):count = 0sum=0for j in range(0,1103):if contours_[1][j][0][1] == i:sum+=contours_[1][j][0][0]count+=1middle=sum/countprint(count)middle_s.append([[middle,i]])#转化成int32类型
contours_middle=np.array(middle_s).astype(np.int32)#这里可以直接把中线上的点打印出来就可以得到中线,但是可能有些噪点
#所以选择用直线拟合,在drawContours()下面直接输出mask就可以看到
cv2.drawContours(mask,contours_middle,-1,(0,255,0),2)#下面把点集放大fitLine()中拟合出直线
output=cv2.fitLine(contours_middle, cv2.DIST_L2, 0, 0.01, 0.01)
k = output[1] / output[0]
b = output[3] - k * output[2]
x_0=-b/k
x_480=(479-b)/k
cv.line(mask,(int(x_0),0),(int(x_480),479),(255,0,0),4)
cv.line(img_c,(int(x_0),0),(int(x_480),479),(255,0,0),4)#展示图片
cv.imshow("mask_line",mask_line)#二值化后拟合轮廓图
cv.imshow("img_c",img_c)#原图画上中线
cv.imshow("line",mask)#二值化,轮廓线和中线
cv.imshow("mask",mask_c)#二值化图像
cv.waitKey(0)

结果图片:

【opencv-python】 HSV抠图-智能车拟合道路边界和中线相关推荐

  1. iPDA“国际智能车联合道路演示”压轴,IEEE IV 2018 圆满落幕!

    导读:由IEEE智能交通系统协会 (ITSS)主办,中国自动化学会.常熟市人民政府.中科院自动化研究所.西安交通大学人工智能与机器人研究所.青岛智能产业技术研究院等机构承办的第29届IEEE国际智能车 ...

  2. 智能车竞赛技术报告 | 智能车视觉 - 太原工业学院 - 晋速-轩辕星

    简 介: 本文详细介绍了太原工业学院"晋速-轩辕星"在第十六届全国大学生智能汽车竞赛智能视觉组的系统方案.本次比赛采用大赛组委会统一指定的新 C 型车模,以NXP公司生产的RT10 ...

  3. 基于“飞桨”的深度学习智能车

    本文作者:吴东昱,北京钢铁侠科技深度学习算法工程师 前言   我在观察历届智能车竞赛以及教学实验中发现,采用传统视觉算法的视觉智能车只能在特定赛道中行驶,一旦赛道环境改变,必须修改大量的代码才能运行. ...

  4. 基于CCD摄像头智能车分段PID控制算法设计

    自动寻迹智能车涉及到当前高技术领域内的许多先进技术,其中最主要的是传感技术.路径规划和运动控制.本课题是以飞思卡尔智能车竞赛为背景,以单片机作为核心控制单元,以摄像头作为路径识别传感器,以直流电机作为 ...

  5. 智能车竞赛技术报告 | 双车接力组 -哈尔滨工业大学 - 紫丁香六队

    简 介: 本文详细介绍了哈尔滨工业大学紫丁香六队在第十六届全国大学生智能汽车竞赛双车接力组的系统方案.我队选择使用官方指定的D车模和F车模来搭建直立和三轮两辆车模,以灵动微电子公司生产的32位单片机 ...

  6. 【智能车Code review】——小S与中S道路判断

    2022.3.10新增订阅通知 近期把此专栏设置为了付费模式,可以直接花9.9买这个专栏,买了就可以直接这个专栏的所有文章了.后续也会更新一些经验贴.也可以进交流群咨询群中大佬问题,查看相关代码以及资 ...

  7. OpenCV+Python 彩色图片的 BGR、灰度图、HSV分量图显示的程序

    OpenCV+Python 彩色图片的 BGR.灰度图.HSV分量图显示的程序 介绍 OpenCV+Python 使用openCV中的split()函数和 cvtColor()函数提取一张彩色图片的B ...

  8. OpenCV + 树莓派制作智能车【1】

    前言 以前制作智能车都是在STM32上制作的,学习了一点OpenCV想要实践一下,一下就想到了买来一直在吃灰的树莓派,做一个智能小车吧! 黑线识别 我们先在Windows上写出基本能跑的检测代码: 首 ...

  9. 通过串口+OpenCv 的智能车图像还原

    做过智能车摄像头的都知道,我们在做车的过程中如果光是看那些单片机传回来的01字符串的图像数据的话,那可是一件相关无聊的事情.不仅如此,看这样的数据还很废眼睛的.这样的话看没过多眼睛就开始累了,就开始不 ...

  10. python opencv 边缘检测 抠图,opencv+python用背景减去法抠图

    opencv+python用背景减去法抠图 opencv+python用背景减去法抠图 import cv2 from matplotlib import pyplot as plt import n ...

最新文章

  1. MQTT——控制报文格式
  2. 【Android 热修复】热修复原理 ( Dex 文件拷贝后续操作 | 外部存储空间权限申请 | 执行效果验证 | 源码资源 )
  3. ftp shell lcd不起作用
  4. linux模式匹配,sed的模式匹配用法探讨
  5. 鼠标点击时隐藏java代码,js实现点击展开隐藏效果(实例代码)
  6. C#中的深度学习:使用OpenCV进行硬币检测
  7. click Documenting Scripts
  8. PAT1019. 数字黑洞
  9. sql server 群集_部署SQL Server以使用群集共享卷进行故障转移群集–第1部分
  10. vue过滤器微信小程序过滤器和百度智能小程序过滤器
  11. 数字化大时代崛起的数据安全能力框架
  12. 阶乘 java_Java 实例 – 阶乘
  13. matlab实现通信系统,香农定理的介绍
  14. spyder 5.0.0 提示依赖项spyder-kernels版本错误
  15. pdf合并软件下载的旗舰版
  16. AD10中创建材料清单(BOM表)
  17. idea各种中文乱码问题
  18. Jacob操作Word文档插入表格并表格中插入图片案例
  19. springboot出入参参数日志打印方案以及实现
  20. 计算机 90学时培训总结,90学时培训心得总结

热门文章

  1. 电脑不用下软件开wifi
  2. C#毕业设计——基于C#+asp.net+sqlserver的计算机等级考试系统设计与实现(毕业论文+程序源码)——计算机等级考试系统
  3. 【转】傅里叶分析之掐死教程(完整版)
  4. JavaSE-接口简单介绍
  5. 苹果6s微信提示未连接服务器,苹果6s微信无法打开,一直显示正在载入怎么处理?...
  6. 变革管理书籍推荐:《组织变革必读12篇》
  7. composer.lock(锁文件)到底要不要提交到项目的版本库中?
  8. DockOne微信分享( 八十八):PPTV聚力传媒的Docker与DevOps
  9. spyder替换_Spyder简单使用
  10. 七剑下天山-告别时域分析的过渡课堂练习-SS2022s