栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

基于python的opencv学习

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于python的opencv学习

基于python的opencv学习 基础知识点

8 bits(位值)-> 256 levels(分辨率)

灰度图像:0黑色-255白色,将灰色分成256级,一层

全彩图像RGB:颜色通道(红、绿、蓝),三层,每层的0-255代表该层颜色的亮度,opencv里是BGR

HSV:色调(H),饱和度(S),明度(V)(增加黑色V减小,增加白色S减小)

H 0-180 ,S 0-255 ,V 0-255

与或非

像素:

VGA:640*480

HD:1280*720

FHD:1920*1080

4K:3840*2160

Opencv中最常用的两种颜色空间转换:BGR<->GRAY,BGR<->HSV

bgr先要变换成hsv再目标检测

uint8:8位无符号整型

opencv基础操作代码: 打开照片:
import numpy as np //python的矩阵库
import matplotlib.pyplot //加入窗口的库
import cv2 as cv

img = cv.imread("Picturelove.jpg")
#要在项目工作空间的文件夹里的照片才行

"""img = cv2.imread("Picturelove.jpg",cv2.IMREAD_GRAYSCALE)"""
#后面的第二参数是转化成灰度图

# C:UserszhaohaobingPycharmProjectspython-opencv-projectpicture

img = cv.resize(img,None,fx = 0.5,fy = 0.5)
#控制输出图像尺寸(图像,要输出的尺寸大小,长宽各变成几倍)
img_dog = cv2.resize(img_dog, (500, 414))
#输出指定长宽

cv.imshow("love",img)
#照片名字不能用中文的

cv.waitKey(0)
#等待时间,毫米级,0代表任意键才终止
cv.destroyAllWindows()
#任意键关闭
cv.imwrite('picture mylove.png',img)
#将照片保存

#res = np.hstack((img1,img2,img3))
#把()里这n张照片放一起

print(img.shape)
#(1200, 1920, 3) h w c(3层还是1层)
print(type(img))
#格式
print(img.size)
#像素点个数
print(img.dtype)
#uint8  数据类型 8位
读取视频:
import numpy as np
import matplotlib.pyplot
import cv2 as cv

vc = cv.VideoCapture("videoHow do you use your time.mp4")
if vc.isOpened():
    open,frame = vc.read()
#open返回一个True或False,vc.read()是取第一帧第二帧...赋给frame
else:
    open = False

while open:
    ret,frame = vc.read()
    if frame is None:
        break
    if ret == True:
        #gray = cv.cvtColor(frame,cv.COLOR_BGRA2GRAY)
        #灰度处理
        cv.imshow("mytime",frame)
        if cv.waitKey(10) == ord("q"):
            #按q键退出键推出视频
            break
vc.release()
cv.destroyAllWindows()
打开摄像头:
import numpy as np
import cv2 as cv

cap = cv.VideoCapture(0)
#一般电脑内置摄像头为0,可以通过设置成 1 或者其他的来选择别的摄像头

if not cap.isOpened():
    print("Cannot open camera")
    exit()

while True:
    # Capture frame-by-frame
    ret, frame = cap.read()
    # if frame is read correctly ret is True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    # Our operations on the frame come here
    #gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)#你也可以注释掉这行颜色转换的代码
    # Display the resulting frame
    cv.imshow('myCamera', frame)
    if cv.waitKey(1) == ord('q'):
        break
# When everything done, release the capture
cap.release()
cv.destroyAllWindows()
保存视频:
#是从摄像头中捕获视频,沿水平方向旋转每一帧并保存它
import numpy as np
import cv2 as cv

cap = cv.VideoCapture(0)
# Define the codec and create VideoWriter object

fourcc = cv.VideoWriter_fourcc(*'XVID')
# ourCC 码以下面的格式传给程序,
# 以 MJPG 为例:cv.VideoWriter_fourcc('M','J','P','G')或者 cv.VideoWriter_fourcc(*'MJPG')。

out = cv.VideoWriter('output.avi', fourcc, 20.0, (640,  480))
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    frame = cv.flip(frame, 0)
    # write the flipped frame
    out.write(frame)
    cv.imshow('frame', frame)
    if cv.waitKey(1) == ord('q'):
        break
# Release everything if job is finished
cap.release()
out.release()
cv.destroyAllWindows()
画线:
import numpy as np
import cv2 as cv

# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((512,512,3), np.uint8)

# Draw a diagonal blue line with thickness of 5 px
#(名字,起始点,终止点,颜色(opencv中是BGR),宽度)
cv.line(img,(0,0),(511,511),(255,0,0),5)

cv.imshow('img', img)
cv.waitKey(0)
画矩形:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((512,512,3), np.uint8)

#(名字,左上坐标,右下坐标,颜色(BGR),框线宽度)
#左上角为(0,0)点,向右x正方向,向下y正方向
cv.rectangle(img,(0,0),(100,100),(0,255,0),3)

cv.imshow('img', img)
cv.waitKey(0)
画圆:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((512,512,3), np.uint8)

#(名字,圆心,半径,颜色(BGR),框线厚度(-1及填鸭))
cv.circle(img,(100,100), 66, (0,0,255), -1)

cv.imshow('img', img)
cv.waitKey(0)
画椭圆:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((512,512,3), np.uint8)

#(名字,中心点,长轴短轴长度,整体沿逆时针方向旋转角度,
# 起始角度,终止角度(是不是完成椭圆),颜色,线框宽度
cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)

cv.imshow('img', img)
cv.waitKey(0)
画多边形:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((512,512,3), np.uint8)

#各个顶点坐标,数据类型int32
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv.polylines(img,[pts],True,(0,255,255))

cv.imshow('img', img)
cv.waitKey(0)
写字:
import numpy as np
import cv2 as cv
# Create a black image
#((h,w,几层),np采用八进制)
img = np.zeros((500,500,3), np.uint8)

#调用函数,写的字赋给font
font = cv.FONT_HERSHEY_SIMPLEX
#(名字,要写的文字,位值,字,字体大小,颜色,字体笔画宽度
# cv.LINE_AA(字体类型)
cv.putText(img,'OpenCV',(10,500), font, 8,(255,255,255),2,cv.LINE_AA)

cv.imshow('img', img)
cv.waitKey(0)
图像的基础操作:
import cv2 as cv

img = cv.imread("pictureme.jpg")

#像素的行和列的坐标获取他的像素值
print(img.item(10,10,2))
#修改像素值
img.itemset((10,10,2),100)
print(img.item(10,10,2))
#获取图像属性(行数,列数, 通道数)
print(img.shape)
#图像的像素数目
print(img.size)
#图像的数据类型
print(img.dtype)
截取选定区域:
import cv2 as cv

img = cv.imread("pictureme.jpg")

#截取选定区域
something = img[0:300, 70:350]
cv.imshow('something',something)
cv.waitKey(0)
Opencv中常用的颜色空间就三种BGR、HSV、灰度:

Opencv中最常用的两种颜色空间转换:BGR<->GRAY,BGR<->HSV

bgr先要变换成hsv再目标检测

import cv2 as cv

img1 = cv.imread("pictureme.jpg")
img2 = cv.imread("pictureme.jpg")

#BGR↔Gray 的转换
hsv1 = cv.cvtColor(img1, cv.COLOR_BGRA2GRAY)
#BGR↔HSV 的转换
hsv2 = cv.cvtColor(img1, cv.COLOR_BGR2HSV)

cv.imshow("img1",hsv1)
cv.imshow("img2",hsv2)
cv.waitKey(0)

H(色彩/色度)的取值范围是 [0,179], S(饱和度)的取值范围 [0,255],V(亮度)的取值范围 [0,255]。

颜色跟踪:

在 HSV 颜色空间中要比在 BGR 空间 中更容易表示一个特定颜色。

import cv2 as cv
import numpy as np

cap = cv.VideoCapture(0)

while True :
    ret,frame = cap.read()
    #每一帧先mask处理
    hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
    #np.array 创建一个数组
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])
    
    
    #mask将符合数值区间的黑白提取出来
    #mask掩膜1、创造一个与原图大小相同的全白图(像素全是1),原图中像素在设置区间里的赋为1,其他像素点赋为0,两张图片进行与运算(都为1才为1),则得到mask(全黑图提取部分为白色)
    mask = cv.inRange(hsv,lower_blue,upper_blue)
   	
    #res将提取出来的在还原颜色
    # frame和frame先取’与‘操作,在用其结果和mask取’与‘操作
    # 将mask中白色地方的颜色在前面结果对应地方中显示出来)
    res = cv.bitwise_and(frame,frame,mask = mask)
    cv.imshow('frame', frame)
    cv.imshow('mask', mask)
    cv.imshow('res', res)
    if cv.waitKey(5) & 0xff ==ord("q"):
        break
cv.destroyAllWindows()
BGR通道分离和合并:
#通道分离
b,g,r = cv.split(frame)
cv.imshow("blue",b)
cv.imshow("green",g)
cv.imshow("red",r)

#第三个通道赋值为零,前面::表示取所有
frame[:,:,2] = 0
#合并
frame = cv.merge([b,g,r])
程序运行时间:
import cv2 as cv

e1 = cv.getTickCount()
#函数a
e2 = cv.getTickCount()
#可得函数a运行时间
time = (e2 - e1)/cv.getTickFrequency()
print(time)

与& 两个1才为1(黑色是0,白色是1,黑色区域不显示,白色区域显示另一张照片颜色)

and

或| 有1就1 (

not

非~ 0变1 1变0

数值操作:
#每个像素点都+10
img_cat2= img_cat +10 

#取前五行,所有列,方面后面打印看部分像素值
img_cat[:5,:,0] 


腐蚀操作:

1、先设置滤波器大小

2、设置迭代次数

3、滤波器从左上依次到右下,如果该地方滤波器内像素剧烈变化,对该地方进行腐蚀,即图形信息变细边小,去掉毛毛刺刺

kernel = np.ones((3,3),np.uint8)  #设置he的大小,he越大每次腐蚀的范围就越大
erosion = cv2.erode(img,kernel,iterations = 1) #迭代次数,迭代此时越多腐蚀越多

cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
膨胀操作:

与腐蚀操作相反,图像变胖

一般先腐蚀去噪,再膨胀恢复

kernel = np.ones((3,3),np.uint8) 
dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 1)

cv2.imshow('dilate', dige_dilate)
cv2.waitKey(0)
cv2.destroyAllWindows()
开运算、闭运算、梯度运算、礼帽、黑帽:(腐蚀、膨胀综合操作)
#例如图像

# 开:先腐蚀,再膨胀 (刺没了)
kernel = np.ones((5,5),np.uint8) 
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

# 闭:先膨胀,再腐蚀 (刺变胖了)
kernel = np.ones((5,5),np.uint8) 
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

# 梯度=膨胀-腐蚀,取膨胀和腐蚀中间的部分
gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)

#礼帽 = 原始输入-开运算结果 (只剩刺)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

#黑帽 = 闭运算-原始输入(只剩刺的轮廓,也可反应主体信息的轮廓)
blackhat  = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)
两照片操作:
import cv2 as cv
import numpy as np

#res = 0.4*cat + 0.6*dog + 0
res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)

#两图片相加
def add_demo(m1,m2):
    dst = cv.add(m1,m2)
    cv.imshow("add_demo",dst)
#两图片相减
def subtract_demo(m1,m2):
    dst = cv.subtract(m1,m2)
    cv.imshow("subtract_demo",dst)

#两照片相乘
def multiply_demo(m1,m2):
    dst = cv.multiply(m1,m2)
    cv.imshow("multiply_demo",dst)

#两照片相除
def divide_demo(m1,m2):
    dst = cv.divide(m1,m2)
    cv.imshow("divide_demo",dst)

#
def logic_demo(m1,m2):
    dst = cv.bitwise_and(m1,m2)
    cv.imshow("bitwise_and", dst)
    
    

img1 = cv.imread("picture班徽(中文).jpg")
img2 = cv.imread("picture班徽En.jpg")
cv.namedWindow('image', cv.WINDOW_NORMAL)

cv.imshow('image1', img1)
cv.imshow('image2', img2)

add_demo(img1,img2)
subtract_demo(img1,img2)
multiply_demo(img1,img2)
divide_demo(img1,img2)


cv.waitKey(0)
cv.destroyAllWindows()
图像阈值:
"""
语法:ret, dst = cv2.threshold(src, thresh, maxval, type)

- dst: 输出图
- src: 输入图,只能输入单通道图像,通常来说为灰度图
- thresh: 阈值
- maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
- type:二值化操作的类型,包含以下5种类型
"""

#cv2.THRESH_BINARY:超过阈值部分取maxval(最大值),否则取0 (二值化)
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)

#cv2.THRESH_BINARY_INV:THRESH_BINARY的反转,超过阈值部分取0,小于部分取最大值
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)

#cv2.THRESH_TRUNC:大于阈值部分设为阈值,小于的不变
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)

#cv2.THRESH_TOZERO:大于阈值部分不改变,小于的设为0
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)

#cv2.THRESH_TOZERO_INV:THRESH_TOZERO的反转,大于阈值部分设为0,小于的不变
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)

titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]

for i in range(6):
    plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()



- cv2.THRESH_TOZERO_INV  THRESH_TOZERO的反转
滤波: 图像梯度-Sobel算子:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-490nIwbE-1647413238967)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencv图像梯度-sobel算子.png)]

Gx是水平方向上的检测,Gy是竖直方向上的检测,检测点是九宫格的中间点,距离中心点近的数值大,中心点梯度检测的权重大

X:右减左 A3-A1+2A6-2A4+A9-A7 得到的值越大梯度越大

"""
语法:
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
(输入照片、图像深度(一般为-1)、dxdy选择进行哪个方向的检测那个赋1另一个为0,ksize是sobel算子大小)
"""
#x方向检测
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
#对图像深度进行取绝对值,以为sobel运算结果可能为负值,在opencv中取值是0-255,为负值以后就变成0,所有要取决绝对值,把负值的部分也显示出来
sobelx = cv2.convertScaleAbs(sobelx)
cv_show(sobelx,'sobelx')

#Y方向检测
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)  
cv_show(sobely,'sobely')

#再求和,(x,权重,y,权重,0(这里是偏置项,设置为0))
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')
均值滤波:

设置一个单位矩阵(he(滤波器)边长需为奇数)例3*3

该he从图像左上角滑动到右下角做内积(对应点相乘)

he的中心点的像素点变为为he内九个像素点的平均值。

# 均值滤波
# 简单的平均卷积操作
blur = cv2.blur(img, (3, 3))

cv2.imshow('blur', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
高斯滤波:

设置一个矩阵(he(滤波器)边长需为奇数)例3*3,中间是1,四种根据远近权重不同

该he从图像左上角滑动到右下角做内积 (对应点相乘)

he的中心点的像素点变为为he内九个像素点的平均值。

# 高斯滤波
# 高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间的
aussian = cv2.GaussianBlur(img, (5, 5), 1)  

cv2.imshow('aussian', aussian)
cv2.waitKey(0)
cv2.destroyAllWindows()
中值滤波:

设置一个he(滤波器)边长需为奇数例3*3

该he从图像左上角滑动到右下角

he的中心点的像素点变为为he内九个像素点的平均值。

# 中值滤波
# 相当于用中值代替
median = cv2.medianBlur(img, 5)  # 中值滤波

cv2.imshow('median', median)
cv2.waitKey(0)
cv2.destroyAllWindows()

三种滤波比较:

中值滤波适合处理椒盐噪声;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tpeBTbRQ-1647413238968)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencv三种滤波.jpg)]

模糊处理去噪:
#均值模糊-去随机噪声
def blur_demo(image):
    dst =  cv.blur(image,(15,1))
    #(1,3)定义一个滤波器一行三列,前值控制横方向的模糊,后值控制纵方向的模糊
    dst = cv.resize(dst ,None,fx = 0.5,fy = 0.5)
    #控制输出图像尺寸(图像,要输出的尺寸大小,长宽各变成几倍)
    cv.imshow("blur_demo",dst)

#中值模糊-去噪椒盐噪声(小黑点)
def median_blur_demo(image):
    dst = cv.medianBlur(image,5)
    cv.imshow("median_blur_demo",dst)

#自定义模糊
def custom_blur_demo(image):
    kernel = np.ones([5,5],np.float32)/25
    #ones([5,5]  5*5大小的全是1的矩阵 /25结果除25保证不溢出
    #kernel = np.array([0,-1,0],[-1,5,-1],[0,-1,0],np.float32)
    #锐化,自定义滤波器总和要为奇数,或=1做增强,=0做边缘
    dst = cv.filter2D(image,-1,kernel = kernel)
    cv.imshow("custom_blur_demo",dst)
Carry边缘检测:

1、去噪,使用高斯滤波器,以平滑图像,滤除噪声。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-omyuyMwX-1647413238969)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencvcanny_1.png)]

2、利用sobel算子计算图像中每个像素点的梯度强度和方向。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-koagvcKX-1647413238969)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencvcanny_2.png)]

3、应用非极大值抑制,以消除边缘检测带来的杂散响应。

(非极大值抑制:即一张图像里有多个目标同时目标相互重叠,这时需要进行非极大值抑制保留概率最大的那个)

4、应用双阈值检测来确定真实的和潜在的边缘。

(即进行两次边界检测保证是边界)

5、通过抑制孤立的弱边缘最终完成边缘检测。

img=cv2.imread("lena.jpg",cv2.IMREAD_GRAYSCALE)

#(picture,minVal,maxval) minVal越小、maxVal越小,保留的边界信息越多
v1=cv2.Canny(img,80,150) 
v2=cv2.Canny(img,50,100)

res = np.hstack((v1,v2))
cv_show(res,'res')

上采样、下采样:

上采样(放大):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RbLEnZwo-1647413238969)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencvPyramid_3.png)]

下采样(缩小):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sm14jstA-1647413238970)(C:UserszhaohaobingAppDataRoamingTyporatypora-zhb-imagespython-opencvPyramid_2.png)]

#上采样,将照片放大
up=cv2.pyrUp(img)
cv_show(up,'up')
print (up.shape)

#下采样,将照片缩小
down=cv2.pyrDown(img)
cv_show(down,'down')
print (down.shape)
轮廓检测:
"""
语法:
cv2.findContours(img,mode,method)
mode:轮廓检索模式
-(默认是它)RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次;

method:轮廓逼近方法,即画轮廓
- CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
- CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。

"""


img = cv2.imread('contours.png')
#先灰度再二值
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
cv_show(thresh,'thresh')

#二值结果,轮廓信息,轮廓层级(传入预处理的图案,检索所有的轮廓,把所有点都画出来)
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

#传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
# 注意需要copy,要不原图会变。。。
#把原图像复制过来操作,避免添加了轮廓信息以后原图像被毁
draw_img = img.copy()
#(被画的图像,轮廓信息,默认-1即把所有轮廓都画上来,轮廓颜色,线条宽度)
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
cv_show(res,'res')

轮廓近似:

在一个图形中,任意两点间连一条线,两点间的曲线上距离该线的最远点的距该线的距离,与阈值作比较

最远距离<阈值:则用该直线代替;

最远距离>阈值:取该点为独立点,与上述两点进行连线,该点与上述两点间各种曲线上的点继续执行上述操作

#轮廓近似
img = cv2.imread('contours2.png')

#先灰度后二值
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

#做轮廓
binary, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

#轮廓阈值设置 0.15*周长
epsilon = 0.15*cv2.arcLength(cnt,True) 
#轮廓近似 = (输入的轮廓,阈值,true)
approx = cv2.approxPolyDP(cnt,epsilon,True)

draw_img = img.copy()
res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
cv_show(res,'res')
高斯模糊:

浮点数计算,耗时耗资源

9*9滤波器 一般拆分成一个横3和一个竖3的两个滤波器,连续处理两次,减少运算量,加快速度

#保证加上噪音后数据还在0-255
def clamp(pv):
    if pv > 255:
        return 255
    if pv < 0:
        return 0
    else :
        return pv
    

#高斯模糊(均值模糊的拓展)基于权重的

#加噪声
def gaussian_noise(image):
    h,w,c = image.shape
    for row in range(0,h,1):
        #从0开始到h每次加1,(row排)
        for col in range(w):#(col列)
            s = np.random.normal(0,20,3)
            #产生随机数的(从0开始到20产生3个
            b = image[row, col, 0] #blue
            g = image[row, col, 1]
            r = image[row, col, 2]
            image[row, col, 0] = clamp(b + s[0])
            image[row, col, 1] = clamp(b + s[1])
            image[row, col, 2] = clamp(b + s[2])
        cv.imshow("noise_image",src)

gaussian_noise(src)

#高斯处理
dst = cv.GaussianBlur(src,(0,0),15)
#15为高斯公式中的一个参值

cv.imshow("Gaussian",dst)
边缘保留滤波:(EPF)(美颜)

色彩边缘处,数据差异太大,不参与均值模糊,保留,即高斯双边模糊,差异位值的左右都模糊,差异位值保留

#双边高斯模糊(磨皮效果)
def bi_demo(image):
    dst = cv.bilateralFilter(image,0,100,15)
    #sigmacolor 取大一点,小的差异模糊掉;sigmaspace取小一点,和会小一点,减小计算量
    cv.imshow("bi_demo",dst)

#均值迁移(会有地方过度模糊)(油画效果)
def shift_demo(image):
    dst = cv.pyrMeanShiftFiltering(image,10,50)
    cv.imshow("bi_demo",dst)
边界填充:
#上下左右填充的多少
top_size,bottom_size,left_size,right_size = (50,50,50,50)


#cv2.copyMakeBorder(图像,上,下,左,右,复制方法)
#BORDER_REPLICATE:复制法,也就是复制最边缘像素
replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)

#BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb  
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)

#BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)

#BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg  
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)

#BORDER_CONSTANT:常量法,常数值填充
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0)


import matplotlib.pyplot as plt
#plt.subplot(列数,行树,本照片在第几个)
plt.subplot(231), plt.imshow(img, 'gray'), plt.title('ORIGINAL')
plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')
plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')
plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')
plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')

plt.show()
模板匹配:

图img1原图,图img2是img1图中一部分,模板匹配就是看img1图中哪个地方最像B

"""
匹配模式:
TM_SQDIFF_NORMED:归一化平方,计算结果越接近0越相关
TM_CCORR_NORMED:归一化相关性,计算结果越接近1越相关
TM_CCOEFF_NORMED:归一化相关系数,计算结果越接近1越相关
"""

#灰度处理以后
#最后一个输入为匹配模式
#res为2从左上到右下遍历完1以后,每个位置得到的差异值,res长宽分布为 X1-X2+1,Y1-Y2+1
res = cv2.matchTemplate(img1,img2,cv2.TM_SQDIFF_NORMED)

#差异化最小值,差异化最大值,差异化最小值时位置的左上坐标,差异化最大值时位置的左上坐标
min_val,max_val.min__loc,max_loc = cv2.minMaxLoc(res)

匹配多个对象:(1中有多个2)

#灰度处理后进行匹配
res = cv2.matchTemplate(img1,img2,cv2.TM_SQDIFF_NORMED)
#设置阈值,预测结果大于0.8的都留下
threshold = 0.8
loc = np.where(res>=threshold)
for pt in zip(*loc[::-1]):  #*表示可选参数
    bottom right = (pt[0] + w , pt [1]+h)
    cv2.rectangle(img_rgb,pt,bottom_right,(0,0,255),2)
cv2.imshow('img.rgb',img reb)
cv2.waitKey(0)
直方图:

bin(横坐标0-255,共256个)

横坐标bin,纵坐标个数,统计图像中不同像素值的个数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MWRDQdRX-1647413238970)(C:UserszhaohaobingAppDataRoamingTyporatypora-user-imagesimage-20210224190221661.png)]

#调用包
def plot_demo(image):
    plt.hist(image.ravel(),256,[0,256])
    plt.show()
#自己写
def image_hist(image):
    color = ('blue','green','red')
    for i,color in enumerate(color):
        hist = cv.calcHist([image],[i],None,[256],[0,256])
        plt.plot(hist, color = color)
        plt.xlim([0,256])
    plt.show()
树莓派教学中的opencv

待整理

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/768462.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号