2025年3月30日 星期日 甲辰(龙)年 月廿九 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

基于Python的OPENCV

时间:10-20来源:作者:点击数:54

OPENCV

预备

导库
  • import cv2#格式BGR
分装展示函数
  • def show(img):
  • cv2.imshow("image",img)
  • #或plt.imshow(img)
  • cv2.waitKey(0)
  • cv2.destroyAllWindows()
读取和保存
  • image=cv2.imread("image.png"
  • #,cv2.IMREAD_COLOR#彩色图
  • ,cv2.IMREAD_GRAYSCALE#灰色
  • )#不支持绝对路径
  • cv2.imwrite("地址",cat)#保存
视频读取
  • vc=cv2.VideoCapture("test.mp4")
  • if vc.isOpened():
  • open,frame=vc.read()
  • else:
  • open=False
  • while open:
  • ret,frame=vc.read()
  • if frame is None:
  • break
  • if ret == True:
  • gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
  • cv2.imshow("name",gray)
  • if cv2.waitKey(20)&0xFF==27:
  • break
切片
  • split_image=image[0:250,0:250]
BGR三通道显示
red
  • image[:,:,0]=0
  • image:,:,1]=0
  • show(image)
green
  • image[:,:,0]=0
  • image:,:,2]=0
  • show(image)
blue
  • image[:,:,1]=0
  • image:,:,2]=0
  • show(image)
像素截断
  • image[:,:,0]+image[:,:,1]
  • #运算前提同型
  • #存在数据自动截断max=255
图片的分与和
  • B,G,R=cv2.split(image)#plt.imshow()
  • image=cv2.merge((B,G,R))
重组像素点
  • new_image=cv2.resize(image,(500,500))
图片融合
  • dog_cat = cv2.addWeighted(dog_image, 0.5, cat_image, 0.5,0)
融合
合并展示
  • all_images=np.hstack(image1,image2,image3)
  • show(all_images)

图像外部填充

  • #cv2.copyMakeBorder(image,top_size,,left_size,,=cv2.BORDER_REPLICATE)
  • cat1=cv2.copyMakeBorder(image
  • ,50#top_size
  • ,50#bottom_size
  • ,50#left_size
  • ,50#right_size
  • ,borderType=cv2.BORDER_REPLICATE#borderType
  • #补充方式若为cv2.BORDER_CONSTANT,多一参数value
  • )
  • """
  • BORDER_REPLICATE:复制法,也就是复制最边缘像素。
  • BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
  • BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
  • BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
  • BORDER_CONSTANT:常量法,常数值填充。
  • """

图像二极化

  • #ret为阈值
  • ret, new_image = cv2.threshold(image
  • , 127
  • , 220
  • ,cv2.THRESH_BINARY
  • )
  • """
  • cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
  • cv2.THRESH_BINARY_INV (THRESH_BINARY的反转)
  • cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
  • cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0
  • cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转
  • """

图像平滑处理

  • #中值滤波(最常用) 3表示3*3范围矩阵
  • new_cat4=cv2.medianBlur(cat,3)
  • #均值滤波
  • new_cat1=cv2.blur(cat,(3,3))
  • #方框率波 normalize=True时与均值滤波同 Flase则不除以3*3
  • new_cat2=cv2.boxFilter(cat,-1,(3,3),normalize=True)
  • #高斯滤波 权重矩阵
  • new_cat3=cv2.GaussianBlur(cat,(3,3),1)
平滑处理

形态学处理

  • #形态学腐蚀操作(增)
  • #iterations表次数
  • qiu=cv2.imread("qiu.png",cv2.IMREAD_GRAYSCALE)
  • N=np.ones((3,3),np.uint8)
  • new_qiu=cv2.erode(qiu,N,iterations=5)
  • show(new_qiu)
  • #形态学膨胀操作(减)
  • N=np.ones((3,3),np.uint8)
  • new_qiu=cv2.dilate(qiu
  • ,N
  • ,iterations=4
  • )
  • show(new_qiu)
  • #开运算,先腐蚀后膨胀(先增后减)
  • new_qiu=cv2.morphologyEx(qiu
  • ,cv2.MORPH_OPEN
  • ,N
  • ,iterations=1
  • )
  • #闭运算,先膨胀后腐蚀(先减后增)
  • new_qiu=cv2.morphologyEx(qiu
  • ,cv2.MORPH_CLOSE
  • ,N
  • ,iterations=1
  • )
  • #梯度运算(膨胀-腐蚀)
  • new_qiu=cv2.morphologyEx(qiu
  • ,cv2.MORPH_GRADIENT
  • ,N
  • ,iterations=1
  • )
  • #礼帽(原始-开结果)
  • new_qiu=cv2.morphologyEx(qiu
  • ,cv2.MORPH_TOPHAT
  • ,N
  • ,iterations=1
  • )
  • #黑帽(闭结果-原结果)
  • new_qiu=cv2.morphologyEx(qiu
  • ,cv2.MORPH_BLACKHAT
  • ,N
  • ,iterations=1
  • )

1为原图,2为腐蚀 3.为膨胀

膨胀和腐蚀

图像梯度边缘处理的算子

Sobel算子
  • #横向右向左,纵向下到上,ksize为算子大小(越大越能抓住更多细节),ddepth=cv2.CV_64F(不知道原因)
  • #横向
  • yuan=cv2.imread("yuan.png",cv2.IMREAD_GRAYSCALE)
  • x_new_yuan=cv2.Sobel(car
  • ,cv2.CV_64F
  • ,1#横向程度
  • ,0#纵向程度
  • ,ksize=3#算子大小
  • )
  • x_new_yuan=cv2.convertScaleAbs(x_new_yuan)
  • #cv2.convertScaleAbs并非简单的取绝对值
  • #纵向
  • y_new_yuan=cv2.Sobel(yuan,cv2.CV_64F,0,1,ksize=3)
  • y_new_yuan=cv2.convertScaleAbs(y_new_yuan)
  • #横纵同时用效果不好
  • #但是可以分别出结果后相融合
  • xy_new_yuan=cv2.addWeighted(x_new_yuan,0.5,y_new_yuan,0.5,0)
  • show(xy_new_yuan)
Scharr算子
  • Sobel等算子有如下缺点:没有充分利用边缘的梯度方向。最后得到的二值图,只是简单地利用单阈值进行处理。
  • yuan=cv2.imread("yuan.png",cv2.IMREAD_GRAYSCALE)
  • x_new_yuan=cv2.Scharr(yuan
  • ,cv2.CV_64F
  • ,1#横
  • ,0
  • #纵
  • )
  • x_new_yuan=cv2.convertScaleAbs(x_new_yuan)
  • #cv2.convertScaleAbs并非简单的取绝对值
  • #纵向
  • y_new_yuan=cv2.Scharr(yuan,cv2.CV_64F,0,1)
  • y_new_yuan=cv2.convertScaleAbs(y_new_yuan)
  • #横纵同时用效果不好
  • #但是可以分别出结果后相融合
  • xy_new_yuan=cv2.addWeighted(x_new_yuan,0.5,y_new_yuan,0.5,0)
  • show(xy_new_yuan)
Laplacian算子
  • yuan=cv2.imread("yuan.png",cv2.IMREAD_GRAYSCALE)
  • x_new_yuan=cv2.Laplacian(yuan,cv2.CV_64F)
  • #x无正负之分故无需
  • #x_new_yuan=cv2.convertScaleAbs(x_new_yuan)
  • show(x_new_yuan)
三者比较
  • #三种算子对比
  • #Sobel算子
  • car=cv2.imread("car.png",cv2.IMREAD_GRAYSCALE)
  • x_new_car=cv2.Sobel(car,cv2.CV_64F,1 ,0,ksize=3)
  • x_new_car=cv2.convertScaleAbs(x_new_car)
  • y_new_car=cv2.Sobel(car,cv2.CV_64F,0,1,ksize=3)
  • y_new_car=cv2.convertScaleAbs(y_new_car)
  • xy_new_car1=cv2.addWeighted(x_new_car,0.5,y_new_car,0.5,0)
  • #Scharr算子
  • x_new_car=cv2.Scharr(car,cv2.CV_64F,1,0)
  • x_new_car=cv2.convertScaleAbs(x_new_car)
  • y_new_car=cv2.Scharr(car,cv2.CV_64F,0,1)
  • y_new_car=cv2.convertScaleAbs(y_new_car)
  • xy_new_car2=cv2.addWeighted(x_new_car,0.5,y_new_car,0.5,0)
  • #Laplacian算子
  • car=cv2.imread("car.png",cv2.IMREAD_GRAYSCALE)
  • xy_new_car3=cv2.Laplacian(car,cv2.CV_64F)
  • #合并
  • all=np.hstack((xy_new_car1,xy_new_car2,xy_new_car3))
  • show(all)
三种算子比较

更优的Canny边缘检测算法

  • Canny边缘检测内部过程
  • 1.使用高斯波分布去除噪声,平滑曲线
  • 2.计算图形像素点梯度和方向
  • 3.应用非极大值抑制,消除边缘杂散影响
  • 4.应用双阈值检测真是和潜在边缘
  • 5.通过抑制孤立弱边缘宛城边缘检测
应用双阈值检测真是和潜在边缘
  • car=cv2.imread("car.png",cv2.IMREAD_GRAYSCALE)
  • new_car=cv2.Canny(car,80,200)#minvalue和maxvalue表为梯度
  • show(new_car)
Canny边缘检测

高斯金字塔

  • #高斯金字塔向下采样法(二倍缩小,更清晰)
  • new_car=cv2.pyrDown(car)
  • #高斯金字塔向上采样法(二倍放大,稍微模糊)
  • new_car=cv2.pyrUp(car)
  • #先后使用后不会与原图同,一般会稍微模糊

直方图均衡化

  • import numpy as np
  • import matplotlib.pyplot as plt
  • han_han=cv2.imread("hanhan.jpg",cv2.IMREAD_GRAYSCALE)
  • equ=cv2.equalizeHist(han_han)
  • two=np.hstack((han_han,equ))
  • show(two)
  • ret,(ax1,ax2)=plt.subplots(1,2,figsize=(10,5))
  • ax1.hist(han_han.ravel(),255)
  • ax2.hist(equ.ravel(),255)
  • ret.subplots_adjust(wspace=0)
  • plt.show()

直方图均衡化

直方图均衡化

均衡化图像素分布

均衡化图像素分布

自适应均衡化

  • import numpy as np
  • import cv2#格式BGR
  • import matplotlib.pyplot as plt
  • def show(img):
  • cv2.imshow("image",img)
  • cv2.waitKey(0)
  • cv2.destroyAllWindows()
  • image1=cv2.imread("hanhan.jpg",0)
  • image2=image1.copy()
  • c=cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
  • #自适应均衡化实例化
  • res=c.apply(image1)
  • #应用
  • all=np.hstack((image1,res))
  • show(all)
  • ret,(ax1,ax2)=plt.subplots(1,2,figsize=(10,5))
  • ax1.hist(image1.ravel(),255)
  • ax2.hist(res.ravel(),255)
  • ret.subplots_adjust(wspace=0)
  • plt.show()
自适应均衡化
像素分布

轮廓检测

  • import numpy as np
  • import cv2#格式BGR
  • def show(img):
  • cv2.imshow("image",img)
  • cv2.waitKey(0)
  • cv2.destroyAllWindows()
  • image=cv2.imread("many_pictures.png")
  • gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
  • #图像二极化
  • ret,thre=cv2.threshold(gray,100,255,cv2.THRESH_BINARY)
  • #contours为所有轮廓
  • contours,hierarchy=cv2.findContours(thre
  • ,cv2.RETR_TREE#轮廓检索方法
  • ,cv2.CHAIN_APPROX_NONE
  • #轮廓逼近方法(另有cv2.CHAIN_APPROX_SIMPLE)
  • )
  • image1=image.copy()
  • new_image=cv2.drawContours(image1#在彩色图上画轮廓边界,灰色图则结果为灰色
  • ,contours#轮廓
  • ,-1#所有索引出的轮廓
  • ,(100,100,55)#BGR定色三原色可随意配色叠加
  • ,2#轮廓宽度
  • )
  • all=np.hstack((image,new_image))
  • show(all)
轮廓检测

轮廓近似

  • import cv2#格式BGR
  • def show(img):
  • cv2.imshow("image",img)
  • cv2.waitKey(0)
  • cv2.destroyAllWindows()
  • #轮廓检测
  • image=cv2.imread("many_pictures.png")
  • gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
  • #图像二极化
  • ret,thre=cv2.threshold(gray,100,255,cv2.THRESH_BINARY)
  • #contours为所有轮廓
  • contours,hierarchy=cv2.findContours(thre
  • ,cv2.RETR_TREE#轮廓检索方法
  • ,cv2.CHAIN_APPROX_NONE
  • #轮廓逼近方法(另有cv2.CHAIN_APPROX_SIMPLE)
  • )
  • image1=image.copy()
  • cnt=contours[1]#第几号轮廓
  • epsilon=0.095*cv2.arcLength(cnt,True)#近似轮廓的近似阈值
  • approx=cv2.approxPolyDP(cnt,epsilon,True)#近似轮廓的生成
  • new_image=cv2.drawContours(image1#在彩色图上画轮廓边界,灰色图则结果为灰色
  • ,[approx]#轮廓
  • ,-1#所有索引出的轮廓
  • ,(0,0,255)#BGR定色三原色可随意配色叠加
  • ,4#轮廓宽度
  • )
  • show(new_image)
轮廓近似

模板匹配

fjj
  • import matplotlib.pyplot as plt
  • import numpy as np
  • import cv2#格式BGR
  • #轮廓检测
  • image=cv2.imread("dog.png",0)
  • template=cv2.imread("dogface.png",0)
  • #标出目标的高和宽
  • height,width=template.shape[:2]
  • methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
  • 'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
  • fig=plt.figure(figsize=(15,9))
  • for i,meth in enumerate(methods):
  • img2 = image.copy()
  • # 匹配方法的真值
  • method = eval(meth)
  • #生成模板匹配次数参数
  • res = cv2.matchTemplate(image, template, method)
  • #相似度和位置参数(不同method,下面参数不同)
  • min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
  • #矩形左上和右下点的确定
  • # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED,取最小值
  • if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
  • top_left = min_loc
  • else:
  • top_left = max_loc
  • bottom_right = (top_left[0] + width, top_left[1] + height)
  • # 画矩形
  • cv2.rectangle(img2#举行图片对象
  • ,top_left#左上位置
  • ,bottom_right#右下位置
  • ,(100,100,55)#RGB边框颜色确定
  • ,2#线条宽度
  • )
  • ax=fig.add_subplot(2,3,i+1)
  • ax.imshow(img2,cmap="gray")
  • ax.set_xticklabels([])
  • ax.set_yticklabels([])
  • ax.set_title(meth,fontsize=10)#标体喝字体大小设置
  • plt.show()
模板匹配
  • 最好使用后三种,因为有归一化,更好地评估模型,注意后两种
  • min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
  • 该句代码各个参数有所不同。

色差问题

色差问题链接

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门