-此部分内容为在学习唐宇迪老师课程中,自己微调后部分知识以及代码,想更多了解移步唐老师课程。*
计算机视觉图像处理Opencv基础知识(附详解代码)上
1.滤波:高斯滤波
2.计算梯度强度及方向 sobel算子
3.非极大值抑制
4.双阈值
5.抑制孤立弱边缘
img = cv2.imread('eagle.jpg',cv2.IMREAD_GRAYSCALE)
v1 = cv2.Canny(img,80,150)
v2 = cv2.Canny(img, 50,100)
res = np.hstack((v1,v2))
cv_show(res,'res')
图像金字塔
img = cv2.imread('pyr.jpg')
cv_show(img,'img')
print(img.shape)
#上采样(对比金字塔,从上而下)
up = cv2.pyrUp(img)
cv_show(up,'up')
print(up.shape)
#下采样(对比金字塔,从下而上)
down = cv2.pyrDown(img)
cv_show(img,'img')
print(down.shape)
down2 = cv2.pyrDown(down)
cv_show(down2,'down2')
print(down2.shape)
up2 = cv2.pyrUp(down2)
up_down = cv2.pyrDown(up2)
cv_show(up_down, 'up_down')
cv_show(np.hstack((down2,up_down)),'up_down2')
拉普拉斯金字塔
Li = Gi - PyrUp(PyrDown(Gi))
img = cv2.imread('giraffe.jpg')
down = cv2.pyrDown(img)
up_down = cv2.pyrUp(down)
l_1 = img - up_down
cv_show(l_1,'l_1')
img = cv2.imread('eagle.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
cv_show(thresh,'thresh')
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
#绘制轮廓
#传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
#一定要使用copy,否则原图会改变
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1,(0,0,255),2)
cv_show(res,'res')
轮廓特征
cnt = contours[1] #取第i+1个轮廓
#面积
cv2.contourArea(cnt)
#周长
cv2.arcLength(cnt,True)
轮廓近似
img = cv2.imread('pipi.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[-1]
draw_img = img.copy()
res = cv2.drawContours(draw_img, [cnt], -1, (0,0,255),2)
cv_show(res,'res')
epsilon = 0.05*cv2.arcLength(cnt, 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')
边界矩阵
img = cv2.imread('pipi.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnt = contours[2]
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w, y+h),(0,255,0),2)
cv_show(img,'img')
area = cv2.contourArea(cnt)
x, y, w, h = cv2.boundingRect(cnt)
rect_area = w * h
extent = float(area) / rect_area
print('轮廓面积与边界矩形比',extent)
#原理类似于卷积
img = cv2.imread('eagle.jpg',0)
template = cv2.imread('eagle_head.png',0)
h,w = 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']
res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)
for meth in methods:
img2 = img.copy()
#匹配方法的真值
method = eval(meth)
print(method)
res = cv2.matchTemplate(img, template, 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] + w, top_left[1] + h)
#画矩形
cv2.rectangle(img2, top_left, bottom_right, 255, 2)
plt.subplot(121), plt.imshow(res, cmap = 'gray')
plt.xticks([]), plt.yticks([]) #隐藏坐标轴
plt.subplot(122), plt.imshow(img2, cmap = 'gray')
plt.xticks([]), plt.yticks([])
plt.suptitle(meth)
plt.show()
匹配多个对象
#匹配多个对象
img_rgb = cv2.imread('circle.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('circle_1.png',0)
h, w = template.shape[:2]
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.8
#取匹配程度大于80%的坐标
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_rgb)
cv2.waitKey(0)
img = cv2.imread('eagle.jpg', 0)
hist = cv2.calcHist([img],[0],None,[256],[0,256])
hist.shape
plt.hist(img.ravel(),256);
plt.show()
img = cv2.imread('eagle.jpg')
color = ('b','g','r')
for i, col in enumerate(color):
histr = cv2.calcHist([img],[i],None, [256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
#创建mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
cv_show(mask, 'mask')
img = cv2.imread('eagle.jpg', 0)
cv_show(img, 'img')
masked_img = cv2.bitwise_and(img, img, mask = mask) #与操作
cv_show(masked_img, 'masked_img')
hist_full = cv2.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv2.calcHist([img],[0],mask,[256],[0,256])
plt.subplot(221), plt.imshow(img,'gray')
plt.subplot(222), plt.imshow(mask,'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)
plt.xlim([0,256])
plt.show()
clahe = cv2.createCLAHE(clipLimit = 2.0, tileGridSize = (8,8))
res_clahe = clahe.apply(img)
res = np.hstack((img, equ, res_clahe))
cv_show(res, 'res')
open-cv中的cv2.dft()以及cv2.idft(),输入图像需要先转换成np.float32格式
img = cv2.imread('eagle.jpg',0)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
# 得到灰度图能表示的形式
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
plt.subplot(121), plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show() # 亮点是低频点,高频点呈发散型
#低通滤波器
img = cv2.imread('eagle.jpg',0)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
rows, cols = img.shape
crow, ccol = int(rows/2), int(cols/2) #找中心位置
#低通滤波
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow - 30 : crow + 30, ccol - 30 : ccol + 30] = 1
#IDFT
fshift = dft_shift * mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])
plt.subplot(121), plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap = 'gray')
plt.title('Result'), plt.xticks([]), plt.yticks([])
plt.show()
#高通滤波器
img = cv2.imread('eagle.jpg',0)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
rows, cols = img.shape
crow, ccol = int(rows/2), int(cols/2) #取中心位置,用以复原
#高通滤波
mask = np.ones((rows, cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 0
#IDFT
fshift = dft_shift * mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0], img_back[:,:,1])
plt.subplot(121), plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap = 'gray')
plt.title('Result'), plt.xticks([]), plt.yticks([])
plt.show()
图像类型:float32
blockSize: 角点检测中指定区域的大小
ksize: Sobel求导中使用的窗口大小
k: 取值参数为[0,4,0.06]
img = cv2.imread('chess.jpg')
print('img.shape',img.shape)
#将gray图像的numpy格式转换为float32格式
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#gray = np.float32(gray)
print(gray.shape)
print(type(gray))
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
print('dst.shape:',dst.shape)
img[dst > 0.01 * dst.max()] = [0, 0, 255]
cv2.imshow('dst',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# SIFT适用于cv2 3.4.1版本以下
cv2.__version__
img = cv2.imread('eagle.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# SIFT尺度变换理论,利用高斯模糊等理论。
sift = cv2.xfeatures2d.SIFT_create()
# kp表示关键特征点的提取
kp = sift.detect(gray, None)
img = cv2.drawKeypoints(gray, kp, img)
cv2.imshow('drawKeypoints', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 计算特征点
kp, des = sift.compute(gray, kp)
print(np.array(kp).shape)
# 尺度处理,提取特征点
sift = cv2.xfeatures2d.SIFT_create()
# 计算两副图像中的特征点
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2,None)
# CrossCheck 表示两个特征点要互相匹配的话,如:A图中的第i个特征点与B图中的第j个特征点最近,且B对A亦然
#NORM_L2: 归一化数组的欧几里得距离
bf = cv2.BFMatcher(crossCheck = True)
#进一步做1对1的匹配
matches = bf.match(des1,des2)
matches = sorted(matches, key = lambda x : x.distance)
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None, flags = 2)
cv_show('img3', img3)
#K对最佳匹配
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
good = []
for m, n in matches:
if m.distance < 0.75 * m.distance:
good.append([m])
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, None, flags = 2)
cv_show('img3', img3)
帧差法、混合高斯模型、光流估计、Lucas-Kanade算法