CV学习笔记(综合)
程序员文章站
2022-03-27 12:54:03
import cv2 as cvimport numpy as npfrom matplotlib import pyplot as pltdef extrace_object_demo(image): capture=cv.VideoCapture("") #输入视频地址 while(True): ret,frame=capture.read() if ret==False: break hsv=cv.cvt...
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
def extrace_object_demo(image):
capture=cv.VideoCapture("") #输入视频地址
while(True):
ret,frame=capture.read()
if ret==False:
break
hsv=cv.cvtColor(frame,cv.COLOR_BGR2HSV) #RGB转换到HSV
lower_hsv=np.array([37,43,46])
high_hsv=np.array([77,255,255])
mask=cv.inRange(hsv,lowerb=lower_hsv,upperb=high_hsv) #像素值处于(lower_hsv,high_hsv)保留,其他置零
cv.imshow("video",frame)
cv.imshow("ss",mask)
c=cv.waitKey(40)
if c==27:
break
def color_space_demo(image): #常用图像格式转换
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
cv.imshow("gray",gray)
cv.waitKey(0)
hsv=cv.cvtColor(image,cv.COLOR_BGR2HSV)
cv.imshow("hsv",hsv)
cv.waitKey(0)
yuv=cv.cvtColor(image,cv.COLOR_BGR2YUV)
cv.imshow("yuv", yuv)
cv.waitKey(0)
ycrcb=cv.cvtColor(image,cv.COLOR_BGR2YCrCb)
cv.imshow("ycrcb", ycrcb)
cv.waitKey(0)
def add_demo(m1,m2): #像素运算,前提是图像形状一致
dst=cv.add(m1,m2)
cv.imshow("add_demo",dst)
def substract_demo(m1,m2): #矩阵像素相减
dst=cv.subtract(m1,m2)
cv.imshow("substract_Demo",dst)
def divide_demo(m1,m2):
dst=cv.divide(m1,m2) #除法运算
cv.imshow("divide_demo",dst)
def others(m1,m2):
h,w=m1.shape[:2]
img=np.zeros([h,w],np.uint8)
m,dev=cv.meanStdDev(img) #计算均值、方差
def logic_demo(m1,m2):
dst=cv.bitwise_and(m1,m2) #逻辑与
cv.imshow(dst)
dst=cv.bitwise_not(m2)
cv.imshow(dst)
dst = cv.bitwise_or(m1, m2)
cv.imshow(dst)
dst = cv.bitwise_xor(m1, m2)
cv.imshow(dst)
def contrast_brightness_demo(image,c,b):
h,w,ch=image.shape[:2]
blank=np.zeros([h,w,ch],image.dtype)
dst=cv.addWeighted(image,c,blank,1-c,b) # 图像融合(image,权重,image,权重)
cv.imshow(dst)
def fill_color_demo(image):
copyImage=image.copy()
h,w=image.shape[:2]
print(image.shape)
mask=np.zeros([h+2,w+2],np.uint8)
#mask:该版本特有的掩膜。 单通道,8位,在长宽上都比原图像image多2个像素点
cv.floodFill(copyImage,mask,(30,30),(0,255,255),(100,100,100),(50,50,50),cv.FLOODFILL_FIXED_RANGE)
# (image, mask, seedPoint起点, newVal填充颜色, loDiff=None, upDiff=None, flags=None)
#CV_FLOODFILL_FIXED_RANGE 时,待处理的像素点与种子点作比较,在范围之内,则填充此像素
#CV_FLOODFILL_MASK_ONLY 此位设置填充的对像, 若设置此位,则mask不能为空,此时,函数不填充原始图像img,而是填充掩码图像.
cv.imshow("fill_color_demo",copyImage)
def fill_binary():
image=np.zeros([400,400,3],np.uint8)
image[100:300,100:300,:]=255
cv.imshow("fill_binary",image)
mask=np.ones([402,402,1],np.uint8)
mask[101:301,101:301]=0
cv.floodFill(image,mask,(200,200),(0,0,255),cv.FLOODFILL_MASK_ONLY)
# CV_FLOODFILL_MASK_ONLY 此位设置填充的对像, 若设置此位,则mask不能为空,此时,函数不填充原始图像img,而是填充掩码图像.
cv.imshow("fill ",image)
#fill_binary()
def blur_demo(image): #均值模糊
dst=cv.blur(image,(1,3),)
cv.imshow("blur_demo",dst)
def median_blur_demo(image): #中值模糊
dst=cv.medianBlur(image,5)
cv.imshow("blur_demo", dst)
def clamp(pv): #限定值函数
if pv>255:
return 255
if pv<0:
return 0
else:
return pv
def gaussion_noise(image): #高斯噪声
h,w,c=image.shape
for row in range(h):
for col in range(w):
s=np.random.normal(0,20,3)
b=image[row,col,0]
g = image[row, col, 1]
r = image[row, col, 2]
image[row,col,0]=clamp(b+s[0])
image[row, col, 1] = clamp(g + s[1])
image[row, col, 2] = clamp(r + s[2])
cv.imshow("gaussion_noise",image)
def bi_demo(image): #能在保持边界清晰的情况下有效的去除噪音
dst=cv.bilateralFilter(image,0,100,15)
# 邻域直径,空间高斯函数标准差,灰度值相似性高斯函数标准差
cv.imshow("bi_demo",dst)
def shift_demo(image): #EPF边缘保留滤波
dst=cv.pyrMeanShiftFiltering(image,10,50)
#dst=cv.pyrMeanShiftFiltering(src,sp,sr,dst,maxLevel=None,termcrit=None)
cv.imshow("shift_demo",dst)
def plot_demo(image): #像素统计成直方图
plt.hist(image.ravel(),256,[0,256],) #ravel方法就是以后个降维的作用
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])
#(src,channle,mask,灰度级的个数,像素范围)
plt.plot(hist,color=color)
plt.xlim([0,256])
plt.show()
def equalHist_demo(image): #增强图像
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
dst=cv.equalizeHist(gray)
cv.imshow("equalHist_demo",dst)
def clahe_demo(image):
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
cv.imshow("gray",gray)
clahe=cv.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
# 直方图均衡化,参数似乎固定,定义一个clach算子
dst=clahe.apply(gray)#计算
cv.imshow("clahe_demo",dst)
def create_rgb_hist(image):#有问题
h,w,c= image.shape
rgbHist =np.zeros([16*16*16,1],np.float32)
bsize =256/16
for row in range(h):
for col in range(w):
b = image[row, col, 0]
g = image[row, col, 1]
r = image[row, col, 2]
index = np.int(b/bsize)*16*16 + np.int(g/bsize)*16 + np.int(r/bsize)
rgbHist[np.int(index),0] =rgbHist[np.int(index),0] + 1
return rgbHist
def hist_compare(image1,image2):
hist1=creat_rgb_hist(image1)
hist2=creat_rgb_hist(image2)
match1=cv.compareHist(hist1,hist2,cv.HISTCMP_BHATTACHARYYA)
match2=cv.compareHist(hist1,hist2,cv.HISTCMP_CORREL)
match3 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR)
print("巴氏距离:%s,相关性:%s,卡方:%s"%(match1,match2,match3))
# 巴氏距离:越小越相似# 相关性:越接近于1越相似# 卡方:越小越相似
cv.imshow("gaussion_noise",image)
def hist2d_demo(image):
hsv=cv.cvtColor(image,cv.COLOR_BGR2HSV)
hist=cv.calcHist([image],[0,1],None,[180,256],[0,180,0,256])
# (src,channle,mask,灰度级的个数,像素范围)
plt.imshow(hist,interpolation='nearest') #一种插值方式
plt.title("hist2d_demo")
plt.show()
def back_projection_demo():
sample=cv.imread("")
target=cv.imread("")
roi_hsv=cv.cvtColor(sample,cv.COLOR_BGR2HSV)
target_hsv=cv.cvtColor(target,cv.COLOR_BGR2HSV)
cv.imshow("sample",sample)
cv.imshow("target", target)
roiHist=cv.calcHist(roi_hsv,[0,1],None,[180,256],[0,180,0,256])
cv.normalize(roi_hsv,roiHist,0,255,cv.NORM_MINMAX)
#cv.normalize(src,dst,alpha=range normalization模式的最小值,
# beta=range normalization模式的最大值,不用于norm normalization(范数归一化)模式。
# ,norm_type=NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用。
# ,dtype=,mask=)
dst=cv.calcBackProject([target_hsv],[0,1],roiHist,[0,180,0,256],1)
#通道数必须与直方图维度相匹配
cv.imshow("back_projection_demo",dst)
def template_demo(image1,image2): #模式匹配
tpl=cv.imread(image1) #目标图形
target=cv.imread(image2)
methods=[cv.TM_SQDIFF_NORMED,cv.TM_CCOEFF_NORMED,cv.TM_CCORR_NORMED] #三种计算匹配相似度的算法
th,tw=tpl.shape[:2]
for md in methods:
result=cv.matchTemplate(target,tpl,md) #计算相似度
min_val,max_val,min_loc,max_loc=cv.minMaxLoc(result) #寻找max min位置
if md==cv.TM_SQDIFF_NORMED:
tl=min_loc
else:
tl=max_loc
br=[tl[0]+tw,tl[1]+th]
cv.rectangle(target,tl,br,(0,0,255),2)
cv.imshow("match"+np.str(md),target)
def threshold(image):
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
print(ret)
cv.imshow("threshold",binary)
def local_threshold(image):
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
binary=cv.adaptiveThreshold(gray,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,25,10)
cv.imshow("local_threshold",binary)
def pyramid_demo(image):
level=3
temp=image.copy()
pyramid_images=[]
for i in range(level):
dst=cv.pyrDown(temp)
pyramid_images.append(dst)
cv.imshow("pyrDown_"+str(i),dst)
temp=dst.copy()
return pyramid_images
def lapalian_demo(image):
pyramid_images=pyramid_demo(image)
level=len(pyramid_images)
print(level)
for i in range(level-1,-1,-1):
if (i-1)<0:
exappend=cv.pyrUp(pyramid_images[i],dstsize=image.shape[:2])
lpls=cv.subtract(image,exappend)
cv.imshow("lapalian_demo_"+str(i),lpls)
else:
exappend = cv.pyrUp(pyramid_images[i], dstsize=pyramid_images[i - 1].shape[:2])
lpls = cv.subtract(pyramid_images[i - 1], exappend)
cv.imshow("lapalian_demo_" + str(i), lpls)
def sobel_demo(image):
grad_x=cv.Scharr(image,cv.CV_32F,1,0)
grad_y = cv.Scharr(image, cv.CV_32F, 0, 1)
gradx=cv.convertScaleAbs(grad_x)
grady=cv.convertScaleAbs(grad_y)
cv.imshow("grad_x",gradx)
cv.imshow("grad_y", grady)
gradxy=cv.addWeighted(grad_x,0.5,grad_y,0.5,0)
cv.imshow("gradxy",gradxy)
def lapalian_demo(image):
dst=cv.Laplacian(image,cv.CV_32F)
lpls=cv.convertScaleAbs(dst)
cv.imshow("lapalian_demo",lpls)
#Canny算法:高斯模糊、灰度转换、计算梯度、非最大信号抑制、高低阈值输出二值图像
def edge_demo(image):
blurred=cv.GaussianBlur(image,(3,3),0)
gray=cv.cvtColor(blurred,cv.COLOR_BGR2GRAY)
xgrad=cv.Sobel(gray,cv.CV_16SC1,1,0)
ygrad = cv.Sobel(gray, cv.CV_16SC1, 0, 1)
edge_output=cv.Canny(xgrad,ygrad,50,150)
cv.imshow("edge_demo",edge_output)
dst=cv.bitwise_and(image,image,mask=edge_output)
cv.imshow("color",dst)
return edge_output
def line_detection_demo(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150, apertureSize=3)
lines = cv.HoughLines(edges, 1, np.pi/180, 200)
print(type(lines))
# 函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线
for line in lines:
rho, theta = line[0] # line[0]存储的是点到直线的极径和极角,其中极角是弧度表示的
a = np.cos(theta) # theta是弧度
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000 * (-b)) # 直线起点横坐标
y1 = int(y0 + 1000 * (a)) # 直线起点纵坐标
x2 = int(x0 - 1000 * (-b)) # 直线终点横坐标
y2 = int(y0 - 1000 * (a)) # 直线终点纵坐标
cv.line(image, (x1, y1), (x2, y2), (0,255, 0), 2)
cv.imshow("image_lines", image)
def line_detect_possoble(image): #直线检测
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150, apertureSize=3)
lines = cv.HoughLinesP(edges, 1, np.pi / 180, 100,minLineLength=50,maxLineGap=10)
for line in lines:
# print(lines)
x1,y1,x2,y2=line[0]
cv.line(image, (x1, y1), (x2, y2), (0,255, 0), 2)
cv.imshow("line_detect_possoble",image)
def detect_circles_demo(image):
cv.pyrMeanShiftFiltering(image,10,100)
cimage = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
circles = cv.HoughCircles(cimage,cv.HOUGH_GRADIENT,1,20,param1=50,param2=30)
circles=np.uint16(np.around(circles))
for i in circles[0,:]:
cv.circle(image,(i[0],i[1]),i[2],(0,0,255),2)
cv.circle(image,(i[0],i[1]),2,(255,0,0),2)
cv.imshow("detect_circles_demo",image)
def contours_demo(image): #边缘检测
# gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
# binary=edge_demo(image)
contours, hierarchy=cv.findContours(binary,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)
for i,contours in enumerate(contours):
#print(contours)
cv.drawContours(image,contours,-1,(0,0,255),2)#填充2-》-1
# 第三个参数指定绘制轮廓list中的哪条轮廓,如果是 - 1,则绘制其中的所有轮廓
print(i)
cv.imshow("contours_demo",image)
def measure_object(image):
dst=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret,binary=cv.threshold(dst,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
# ret:True或False,代表有没有读到图片;
# dst:binary 目标图像;
cv.imshow("threshold",binary)
gray_rgb=cv.cvtColor(binary,cv.COLOR_GRAY2RGB)
contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
# cv2.RETR_EXTERNAL表示只检测外轮廓 .RETR_LIST检测的轮廓不建立等级关系
# cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1
# cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标
# cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。
for i, contour in enumerate(contours):
area=cv.contourArea(contour) #计算轮廓面积
x,y,w,h=cv.boundingRect(contour)#得出轮廓的个点坐标
rate=min(w,h)/max(contour)
print(rate)
mm=cv.moments(contour)
cx = mm["m10"] / mm["m00"]#图像重心坐标(cx,cy)
cy = mm["m01"] / mm["m00"]
cv.circle(image,(np.int(cx),np.int(cy)),3,(0,0,255),-1)
cv.rectangle(image,(x,y),(x+2,y+h),(0,0,255),2)
approx=cv.approxPolyDP(contour,4,True)#把一个连续光滑曲线折线化
# curve:输入曲线,数据类型可以为vector < Point >。
# approxCurve:输出折线,数据类型可以为vector < Point >。
# epsilon:判断点到相对应的line
# 的距离的阈值。(距离大于此阈值则舍弃,小于此阈值则保留,epsilon越小,折线的形状越“接近”曲线。)
# closed:曲线是否闭合的标志位。
print(approx.shape)
if approx.shape[0]>10:
cv.drawContours(gray_rgb,contours,i,(0,0,255),2)
if approx.shape[0]>6:
cv.drawContours(gray_rgb,contours,i,(255,0,255),2)
cv.imshow("measure_object",image)
def erode_demo(image):#腐蚀
print(image.shape)
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(dst, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
kernel=cv.getStructuringElement(cv.MORPH_RECT,(3,3))
dst=cv.erode(binary,kernel)
cv.imshow("erode_demo",dst)
def dilate_demo(image):#膨胀
print(image.shape)
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(dst, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
kernel=cv.getStructuringElement(cv.MORPH_RECT,(3,3))
dst=cv.dilate(binary,kernel)
cv.imshow("dilate_demo",dst)
def open_demo(image): #开运算:先腐蚀后膨胀,开运算可以用来消除小的块,纤细点处分离物体,并在平滑较大的物体边界的同事不明显的改变其面积
print(image.shape)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(dst, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
kernel=cv.getStructuringElement(cv.MORPH_RECT,(5,5))
binary=cv.morphologyEx(binary,cv.MORPH_OPEN,kernel)
cv.imshow("open_demo",binary)
def close_demo(image):#闭运算:先膨胀后腐蚀,消除小型的黑洞,
print(image.shape)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(dst, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
kernel=cv.getStructuringElement(cv.MORPH_RECT,(15,15))
binary=cv.morphologyEx(binary,cv.MORPH_CLOSE,kernel)
cv.imshow("close_demo",binary)
def top_hat_demo(image):#顶帽:原图像与开操作差值图像
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
kernel=cv.getStructuringElement(cv.MORPH_RECT,(5,5))
# 返回指定形状和尺寸的结构元素。
# 这个函数的第一个参数表示内核的形状,有三种形状可以选择。
# 矩形:MORPH_RECT;
# 交叉形:MORPH_CROSS;
# 椭圆形:MORPH_ELLIPSE;
dst=cv.morphologyEx(gray,cv.MORPH_TOPHAT,kernel)#进行各类形态学的变化
# src传入的图片
# op进行变化的方式
# kernel表示方框的大小
cimage=np.array([gray.shape,np.uint8])#提升亮度
cimage=100
cv.add(dst,cimage)
cv.imshow("top_hat_demo",dst)
def hat_gray_demo(image): # 灰帽
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(dst, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # 改变第一个参数即可进行其他形态学操作
dst = cv.morphologyEx(binary, cv.MORPH_TOPHAT, kernel)
cv.imshow("top_hat_demo", dst)
def hat_binary_demo(image): # 灰帽
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(dst, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # 改变第一个参数即可进行其他形态学操作
dst = cv.morphologyEx(binary, cv.MORPH_GRADIENT, kernel)
cv.imshow("top_hat_demo", dst)
#基于距离的分水岭算法:灰度、二值、距离变换、寻找种子、生成marker、分水岭变换、输出
def watershed_demo(src):
# print(src.shape)
blurred = cv.pyrMeanShiftFiltering(src, 10, 100) #边缘保留滤波去噪
# 灰度二值化
gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY) #转化为灰度图
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU) #二值化
cv.imshow("binary-image", binary)
# 形态学操作
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3)) #构造结构
mb = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel, iterations=2)
sure_bg = cv.dilate(mb, kernel, iterations=3)
cv.imshow("mor-opt", sure_bg)
# 距离转换
dist = cv.distanceTransform(mb, cv.DIST_L2, 3)#距离变化(提取出我们确信它们是硬币的区域)
dist_output = cv.normalize(dist, 0, 1.0, cv.NORM_MINMAX)#归一化
dist_output1 = np.uint8(dist_output)
ret, surface = cv.threshold(dist, dist.max()*0.6, 255, cv.THRESH_BINARY)
surface_fg = np.uint8(surface)#将float类型转化为uint
cv.imshow("surface-bin", surface_fg)
unknown = cv.subtract(sure_bg, surface_fg)#除种子以外的区域(剩下的区域是我们不知道的区域,无论是硬币还是背景.分水岭算法应该找到它)
ret, markers = cv.connectedComponents(surface_fg)
#求连通区域(创建标记:它是一个与原始图像相同大小的数组,但使用int32数据类型,并对其内部的区域进行标记.)
# watershed transform 分水岭变换
markers = markers + 1 # Add one to all labels so that sure background is not 0, but 1
markers[unknown==255] = 0 # mark the region of unknown with zero
markers = cv.watershed(src, markers=markers)
src[markers==-1] = [0, 0, 255]#标记
cv.imshow("result", src)
def face_detect_demo(image):
cv.CascadeClassifier()
src = cv.imread("E:\\BaiduNetdiskDownload\\opencv-python\\coins.jpg")
cv.namedWindow("imput image",cv.WINDOW_AUTOSIZE)
cv.imshow("imput image",src)
watershed_demo(src)
#threshold(src)
# b,g,r=cv.split(src)
# cv.imshow("blue",b)
##ROI操作
# face=src[50:250,100:300]
# gray=cv.cvtColor(face,cv.COLOR_BGR2GRAY)
# backface=cv.cvtColor(gray,cv.COLOR_GRAY2RGB)
# src[50:250,100:300]=backface
# cv.imshow("a",src)
#fill_color_demo(src)
# src[:,:,0]=0
# src=cv.merge([b,g,r])
#blur_demo(src)
cv.waitKey(0)
# color_space_demo(src)
cv.destroyAllWindows()
本文地址:https://blog.csdn.net/weixin_46612732/article/details/107311143
下一篇: AdminLTE框架的使用