在vs2017中配置opencv
vs中配置
配置环境变量
API函数
读取图像 - imread
Mat 类型是opencv中存储图像的数据类型(本质就是二维矩阵)
imread() 有两个参数,第一个必须是路径,第二个参数是关于图像色彩,如:IMREAD_GRAYSCALE是显示灰度图像
eg:
Mat src=imread("D:/lsl.jpg");
显示图像 - imshow
imshow() 有两个参数,第一个是窗口名称,第二个参数是图像的数据对象
eg:
imshow("input",src);
显示图像 - waitKey
一个参数,表示间隔多少毫秒
eg:
waitKey(0)
0代表一直停顿,100代表停顿100毫秒
销毁所有窗口 - destroyAllWindows
创建一个窗口 - namedWindows
两个参数,第一个是窗口名,第二个是窗口大小
eg:
namedWindows("输入窗口",WINDOW_FREERATIO);
WINDOW_FREERATIO代表自动窗口大小
色彩空间转换函数 - cvtColor
COLOR_BGR2GRAY = 6 彩色到灰度
COLOR_GRAY2BGR = 8 灰度到彩色
COLOR_BGR2HSV = 40 BGR到HSV
COLOR_HSV2BGR = 54 HSV到BGR
图像保存 - imwrite
第一个参数是图像保存路径
第二个参数是图像内存对象
车道识别实战
Canny边缘检测算法
原理:通过求取图像上的每一个像素点周边像素变化梯度,来确定这个点是否是边缘。若这个点左右像素点变化梯度较大,则这个点更可能是边缘点。首先,利用高斯核进行高斯滤波,对图片去噪。然后计算梯度的幅值和方向(一阶偏导的有限差分),选取四个方向(类似*)进行像素点梯度计算,将四个方向的梯度值综合起来,得到某个像素点的总梯度值,表示像素周围图像变化情况。使用双阈值抑制弱边缘,梯度大于大阈值的点一定是边缘点称为强边缘,小于小阈值的点一定不是边缘点,位于大阈值和小阈值之间的点成为弱边缘,若弱边缘与强边缘相连则是边缘,不相连则不是。
Canny(img, 50, 100)
三个参数,第一个是进行边缘检测的图片,第二个是小阈值,第三个是大阈值
ROI mask
ROI region of interest 感兴趣的部分
从原图中扣出自己感兴趣的部分(类似抠图)
C++版本的opencv中有ROI接口,python中没有
数组切片 针对矩形区域
布尔运算(与运算) 针对非矩形区域
通过和原图同样大小的掩码来实现,0代表不保留,1代表保留,原图与掩码图进行与运算获取需要部分
先获取跟原图大小相同的掩码图像(np.zeros_like ),再通过(cv2.fillPoly)填充掩码图,最后通过(cv2.bitwise_and)将掩码图与原图做与运算
np.zeros_like 获得和原图大小相同的数组存掩码图像
一个参数相同的图像数组名
cv2.fillPoly 填充多边形
三个参数,第一个是填充数组,第二个构建多边形的顶点,第三个填充的颜色。
如cv2.fillPoly(mask, np.array([[[0, 368], [310, 210], [310, 210], [640, 368]]]), color=255)
cv2.bitwise_and 与运算
两个参数,第一个要截取图像数组,第二个是与运算图像数组
霍夫变换
霍夫变换是从图片中获取直线或者圆的算法,只支持灰度图
中心思想:在直角坐标系中,做一条垂直于该直线的经过原点的垂线,此时该垂线长度为r,垂线与x轴的夹角为theta。通过该r与theta的值就可以唯一确定一条直线。theta确定了直线的斜率,而r确定直线的位置。与极坐标的表示方法类似但意义不同。不直接用y=kx+b是因为若直线垂直时,k是无穷大,计算机不好表示。遍历图像矩阵,在r,theta将矩阵中记录边缘点位置,类似于投票的过程。得票数越多,越可能是直线,因为在同一直线上的点r,theta值相同,也就是说在r,theta矩阵中位置相同。
cv2.HuoghLinesP(edge_img, 1, np.pi / 180, 15, minLineLength=40, maxLineGap=20)
参数一:要检测的图片矩阵
参数二三四是对交点判定的置信区间
参数二:距离r的精度,值越大,考虑越多的线
参数三:距离theta的精度,值越大,考虑的线越多
参数四:累加数阈值,值越小,考虑越多的线
minLineLength:最短长度阈值,短于这个长度的线被排除
maxLineGap:同一直线两个点间的最大距离
返回值:返回一个列表,列表中每一个元素是个1*4的数组,表示每个线段起点终点坐标值
[np.array([[x_1,y_1,x_2,y_2]]),
np.array([[x_1,y_1,x_2,y_2]]),
.......
np.array([[x_1,y_1,x_2,y_2]])
]
离群值过滤
剔除掉通过误差造成的直线
先将所有直线按照斜率正负分为两条车道线,存在两个列表中
计算出左右两组直线的平均斜率,如果某条直线的斜率与平均斜率相差较大,就认为这条直线是个噪点,将其过滤
通过自定义函数实现
最小二乘拟合
将所有表示左车道的直线拟合成一条直线,将所有表示右车道的直线拟合成一条直线
利用np.ravel,分别取出所有点x坐标和y坐标
通过np.ployfit,进行多项式拟合,得到多项式系数
利用np.ployval,计算直线上两个个点,用于唯一确定这条直线
np.ravel:将高维数组拉成一维
np.polyfit:多项式拟合,多个参数,前面参数是要拟合数据,最后一个参数是拟合为几次曲线
np.polyval:多项式求值,两个参数,第一是多项式系数,第二个是x值
画车道线
cv2.line 五个参数,第一个是在哪个图像上绘制图形,第二个第三个是线段的起始点和终止点,第四个参数是线段颜色,第五个参数是线段宽度
opencv读写视频流
cv2.VideoCapture
一个参数,视频名
read函数,两个返回值,第一个是当前视频流是否关闭,第二个是当前视频流帧的图像
如:
capture = cv2.VideoCapture('Video.mp4)
ret,frame = capture.read()