赞
踩
常用的色彩空间有:RGB/RGBA/GRAY/HSV/YUV
(1)RGB/RGBA:RGB是三通道,即红绿蓝三个通道;RGBA是四通道,比RGB多了个透明度。
RGB色彩模式是工业界的一种颜色标准,是通过对红( R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。
(2)GRAY:即灰度图像,单通道。
(3)HSV:H是色彩/色度,取值[0, 179],S是饱和度,取值[0, 255],V是亮度,取值[0, 255]。但是由于软件使用的值不同,取值范围也不同。通常需要拿openCV的HSV值和其他软件的HSV值进行对比时,要记得使用归一化处理。
(4)YUV:是一种彩色编码系统,主要用在视频、图像处理流水线中。
YUV是一种颜色空间,基于YUV的颜色编码是流媒体的常用编码方式。Y表示流明,U、V表示色度、浓度,这种表达方式起初是为了彩色电视与黑白电视之间的信号兼容。 对于图像每一点,Y确定其亮度,UV确认其彩度。
# openCV读取图片时候的初始格式是BGR格式
img1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)
img3 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img4 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
openCV内置的基本图形绘制有:直线、矩形、圆形、椭圆、多边形、文字。
import cv2
img = cv2.imread("")
# 坐标轴是从左上角到右下角
cv2.line(img, (100, 30), (210, 180), color=(0, 0, 255), thickness=2) # 直线 参数:坐标点1,2 绘制颜色 粗度
cv2.circle(img, (50, 50), 30, (0, 0, 255), 1) # 圆形 参数:圆心 半径 颜色 粗度
cv2.rectangle(img, (100, 30),(210, 180), color=(0, 0, 255), thickness=2) # 矩形 参数: 对角点1,2 颜色 粗度
cv2.ellipse(img, (100, 100), (100, 50), 0, 0, 360, (255, 0, 0), -1) # 椭圆 参数:圆心(1,2) 长短轴(1,2) 旋转角度 起始角度 颜色 粗度 默认-1
cv2.polylines(img, [pts], True, (0, 0, 255), 2) # 多边形 参数:所有角坐标 是否闭合 颜色 粗度
cv2.putText(img, 'hello world!', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1, lineType=cv2.LINE_AA) # 文字 参数:添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细
cv2.imshow("pic", img)
(1)什么是二值化?
图像的二值化,就是将图像上的像素点的灰度值设置为0或255(0或1),也就是将整个图像呈现出明显的只有黑和白的视觉效果。
(2)二值化的类型有哪些?
OTSU二值化,普通二值化,自适应阈值二值化。
(不同类型的二值化本质区别是,如何找到一个界限来划分二值化。)
#
img = cv2.imread('', 0)
ret, th1 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSH)
th2 = cv2.adaptiveThreshold(img, 255,
ret, th2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
#自适应阈值
th3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
th4 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
图像存储数据的本质就是张量,所以图像运算的本质是矩阵运算。
(1)加减:对应位置相加减。(INT8,值域在0-255之间,超过255,设置为255,低于0,设置为0)
cv2.add(x, y)
cv2.subtract(x,y)
(2)图像混合:本质上也是图像相加,根据两幅图像的权重不同相加,给人一种混合或者透明感。
dst = cv2.addweighted(img1, 0.7, img2, 0.3, 0)
(3)按位运算:常用按位操作有,与AND,或OR,非NOT,异或XOR等。
import cv2 img1 = cv2.imread('') img2 = cv2.imread('') rows, cols, channels = img2.shape roi = img1[0:rows, 0:cols] img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY) ret,mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY) mask_inv = cv2.bitwise_not(mask) # cv2.imshow("mask_inv", mask_inv) img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv) # cv2.imshow("img1_bg ", img1_bg ) img2_fg = cv2.bitwise_and(img2, img2, mask=mask) # cv2.imshow("img2_fg ", img2_fg ) det = cv2.add(img1_bg, img2_fg) img1[0:rows, 0:cols]=dst cv2.imshow('res', img1) cv2.waitKey(0)
(1)resize/transpose/flip 缩放/旋转/翻转
img_resize = cv2.resize(img, Size, fx, fy, interpolation) # size 缩放后的尺寸, fx,fy缩放系数 interpolation 选项所用的插值方法 默认双线性插值
img_trans=cv2.transpose(img) # 逆时针旋转90° 即矩阵转置
img_flip0=cv2.flip(img,0) # 参数:大于0表示沿y轴翻转,等于0表示沿x轴翻转,小于0表示 x和y同时翻转
(2)仿射变换 (线性变换): 任意一个二维图像,乘以一个仿射矩阵,就能得到仿射变换后的图像。(缩放、旋转、位移、倾斜、镜像)
rot_mat = cv2.getRotationMatrix2D(center, -5, 1) # 获得仿射变换矩阵(旋转)
# center表示中间点的位置,-5表示逆时针旋转5度,1表示进行等比列的缩放
cv2.warpAffine(img, rot_mat, (img.shape[1], img.shape[0])) # 仿射运算
# img表示输入的图片,rot_mat表示仿射变化矩阵,(image.shape[1], image.shape[0])表示变换后的图片大小
(3)透视变换:将图片投影到一个新的视平面,也称作投影映射。
M = cv2.getPerspectiveTransform(pts1, pts2) # 参数:原来透视变换前坐标点位置, 透视变换后坐标点的位置
dst = cv2.warpPerspective(img, M, (200, 201))
(4)膨胀/腐蚀 (二值化图像)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) # 定义膨胀/腐蚀的核
dst_dilate = cv2.dilate(img, kernel) # 膨胀
dst_erode = cv2.erode(img, kernel) # 腐蚀
(5)开/闭/梯度/礼帽/黑帽
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) # 定义核
dst_open = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) # 开
dst_close = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) # 闭
dst_grad = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) # 梯度
dst_tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) # 顶帽/礼帽
dst_black = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel) # 黑帽
(1)什么是滤波?
滤波过程就是把不需要的信号频率去掉的过程/
滤波操作通过卷积操作来实现,卷积核一般称为滤波器。常见的滤波分为:低通滤波、高通滤波、中通滤波、阻带滤波。
滤波分析一般分为时域分析核频域分析。
(2)什么是频域和时域。
时域就是信号随着时间变化得到不同的取值;频域是根据不同频率的信号得到的频谱图。两者可以通过傅里叶变换和傅里叶逆变换实现相互的转换。
(以下的操作都是在时域上通过卷积操作进行的)
(3)卷积操作:卷积操作的本质就是卷积核在图像在从左到右从上到下扫描进行卷积,得到新的图像。(称为特征图)
(4)平滑操作:通过定义一个平滑算子(低通滤波器),对图像进行卷积操作。
平滑算子:均值滤波,高斯滤波,中值滤波,双边滤波。
(5)锐化操作:通过定义一个锐化算子(高通滤波器),对图像进行卷积操作。
锐化算子:Laplacian算子。
USM锐化算法:原图的2倍减去高斯滤波后的图像。
kernel_1 = np.array([[1,1,0],[1,0,-1],[0,-1,-1]], np.float32) # 高通滤波器 Laplacian算子
dst_1 = cv2.filter2d(src, -1, kernel=kernel_1) # 滤波运算
dst_2 = cv2.blue(src, (5,5)) # 均值滤波 定义5*5的均值滤波
dst_3 = cv2.GaussianBlur(src, (5,5), 1) # 高斯滤波 定义5*5的高斯滤波 1: 方差为1的高斯滤波 对高斯噪声平滑处理很好
dst_4 = cv2.medianBlur(src, 5) # 中值滤波 定义5*5的中值滤波 对椒盐噪声平滑处理很好
(6)梯度操作:通过定义一个梯度算子(滤波器),对图像进行卷积操作。(梯度一般有两个方向,一个横轴x,一个竖轴y)
梯度算子:Sobel,Scharr和Laplacian梯度滤波器。
img_x = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) # X方向 sobel
img_y = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) # y方向 sobel
img_XY = cv2.Sobel(img, cv2.CV_64F, 1, 1, ksize=3) # xy方向 sobel
img_lap = cv2.Laplacian(img,cv2.CV_16S,ksize = 3) # laplacian
abs_X = cv2.convertScaleAbs(img_x) # 转回uint8
abs_Y = cv2.convertScaleAbs(img_y) # 转回uint8
abs_XY = cv2.convertScaleAbs(img_XY) # 转回uint8
abs_lap = cv2.convertScaleAbs(img_lap)
cv2.imshow("abs_X", abs_X)
cv2.imshow("abs_Y", abs_Y)
cv2.imshow("abs_XY", abs_XY)
cv2.imshow('laplacian',abs_lap)
cv2.waitKey(0)
(1)Canny算法的流程:
① 彩色图像转换为灰度图像;
② 高斯滤波,滤除噪声点;
③ 计算图像梯度,根据梯度计算边缘幅值与角度;
④ 非极大值抑制;
⑤ 双阈值边缘连接处理;
⑥ 二值化图像输出结果。
(2)什么是非极大值抑制?
非极大值抑制是一种边缘稀疏技术,非极大值抑制的作用在于瘦边。即找到梯度最大的,对其他的进行抑制(消去)。对图像进行梯度计算后,仅仅基于梯度值提取的边缘仍然很模糊。使用这种方法,可以使得边缘只保留一个像素。
步骤:
(3)什么是双阈值边缘连接处理?
这一步主要用来确定边缘,即哪些边缘是边缘,哪些不是。因此通过两个阈值,minVal和maxVal,当图像的灰度梯度高于maxVal时被认为是真的边界,那些低于 minVal 的边界会被抛弃。如果介于两者之间的话,就要看这个点是否与某个被确定为真正的边界点相连,如果是就认为它也是边界点,如果不是就抛弃。
(4)代码:
import cv2
img = cv2.imread("0.jpg", 0)
cv2.imshow('src', img)
img = cv2.convertScaleAbs(img, alpha=6, beta=0) #提高对比度
cv2.imshow('abs', img)
img = cv2.GaussianBlur(img, (5,5), 0)
canny = cv2.Canny(img, 50, 150) # 参数: 双阈值检测中两个参数
canny = cv2.resize(canny, dsize=(500, 500))
cv2.imshow('canny', canny)
cv2.waitKey(0)
(1)opencv如何查找轮廓信息?
轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法。所以边缘提取的阈值选定会影响最终轮廓发现结果。
它是通过搜索二值图像上的边缘拐点,然后进行连接,绘制轮廓。
(2)代码:
函数详解——寻找图像轮廓findContours()
# 函数内置canny
coutours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# RETR_TREE:提取所有轮廓并重新建立网状轮廓结构
# CHAIN_APPROX_NONE:获取每个轮廓的每个像素,相邻的两个点的像素位置差不超过1
# CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,值保留该方向的重点坐标,如果一个矩形轮廓只需4个点来保存轮廓信息
img_contour = cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
(3)轮廓面积、周长、重心:
area = cv2.contourArea(contours[0]) # 面积
perimeter= cv2.arcLength(contours[0], True) # 周长
M= cv2.moment(contours[0]) # 重心
(4)轮廓近似:
简单来说,就是findContours函数得到轮廓中的坐标点后,approx对图像轮廓点进行多边形拟合
epsilon = 40 # 精度 就是另个轮廓点之间最大距离数
approx = cv2.approxPolyDP(contours[0], epsilon, True)
img_contour = cv2.drawContours(img, [approx], -1, (0, 255, 0), 3)
(5)凸包与凸性检测
convexHull():检测曲线是否有凸性缺陷,并能矫正缺陷。(凹进去就被叫做凸性缺陷)
isContourConvex():检测曲线是否为凸,只能返回True或False。
hull = cv2.convexHull(contours[0]) #
f = cv2.isContourConvex(contours[0]) # 原始为凹 False
t = cv2.isContourConvex(hull) # 矫正后为凸 True
(6)边界检测
mport cv2 import numpy as np img = cv2.imread('16.jpg') imggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imggray, 127, 255, 0) contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 边界矩形 x, y, w, h = cv2.boundingRect(contours[0]) img_contour = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2) # 最小矩形 rect = cv2.minAreaRect(contours[0]) box = cv2.boxPoints(rect) box = np.int0(box) img_contour = cv2.drawContours(img, [box], 0, (0, 0, 255), 2) # 最小外切圆 (x, y), radius = cv2.minEnclosingCircle(contours[0]) center = (int(x), int(y)) radius = int(radius) img_contour = cv2.circle(img, center, radius, (255, 0, 0), 2) cv2.imshow("img_contour", img_contour) cv2.waitKey(0)
(7)轮廓性质
x,y,w,h = cv2.boundingRect(cnt)
aspect_ratio = float(w/h)
area = cv2.contourArea(cnt)
x,y,w,h = cv2.boundingRect(cnt)
rect_area = w*h
extent = float(area/rect_area )
area = cv2.contourArea(cnt)
hull = cv2.convexHull(cnt)
hull_area = cv2.contourArea(hull)
solidity= float(hull/hull_area )
area = cv2.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi)
import cv2 import numpy as np img = cv2.imread('16.jpg') imggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imggray, 127, 255, 0) contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 椭圆拟合 ellipse = cv2.fitEllipse(contours[0]) cv2.ellipse(img, ellipse, (255, 0, 0), 2) # 直线拟合 h, w, _ = img.shape [vx, vy, x, y] = cv2.fitLine(contours[0], cv2.DIST_L2, 0, 0.01, 0.01) lefty = int((-x * vy / vx) + y) righty = int(((w - x) * vy / vx) + y) cv2.line(img, (w - 1, righty), (0, lefty), (0, 0, 255), 2) cv2.imshow("img_contour", img) cv2.waitKey(0)
(1)什么是图像金字塔?
图像金字塔就是将一张图片,按不同的比例缩放,形成一组不同尺寸大小的图片。(即,下采样和上采样)
(2)什么是高斯金字塔和拉普拉斯金字塔,两者有什么区别?
高斯金字塔(Gaussianpyramid): 先进行高斯模糊,再等比例缩放。(上采样/下采样缩放)
上采样一定会造成照片的模糊。
拉普拉斯金字塔(Laplacianpyramid): 用来从金字塔低层图像重建上层未采样图像,在数字图像处理中也即是预测残差,可以对图像进行最大程度的还原,配合高斯金字塔一起使用
两者的简要区别:高斯金字塔用来向下降采样图像,注意降采样其实是由金字塔底部向上采样,分辨率降低,它和我们理解的金字塔概念相反(注意);而拉普拉斯金字塔则用来从金字塔底层图像中向上采样重建一个图像。
(3)代码:
高斯金字塔:
import cv2
img = cv2.imread(r"13.jpg")
for i in range(3):
cv2.imshow(f"img{i}",img)
# img = cv2.pyrDown(img)
img = cv2.pyrUp(img)
cv2.waitKey(0)
拉普拉斯金字塔
import cv2
img = cv2.imread(r"12.jpg")
img_down = cv2.pyrDown(img)
img_up = cv2.pyrUp(img_down)
img_new = cv2.subtract(img, img_up)
#为了更容易看清楚,做了个提高对比度的操作
img_new = cv2.convertScaleAbs(img_new, alpha=5, beta=0)
cv2.imshow("img_LP", img_new)
cv2.waitKey(0)
根据数学公式,找出图像中对应的形状。(极坐标/直角坐标转换为霍夫空间,再根据数学公式找到符合的形状)
代码:
(1)检测直线
import cv2 import numpy as np image = cv2.imread("lines.jpg") image_2 = image.copy() image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(image_gray, 100, 150) lines = cv2.HoughLines(edges, 1, np.pi / 180, 150) for line in lines: rho, theta = line[0] a = np.cos(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)) # 直线终点纵坐标 cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) imgs = np.hstack([image_2,image]) cv2.imshow("image_lines", imgs) cv2.imwrite("test.jpg",imgs) cv2.waitKey(0)
(2)检测圆形
import cv2 import numpy as np rawImage = cv2.imread("circles.jpg") image = cv2.GaussianBlur(rawImage, (3, 3), 1) image_gray = cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY) edges = cv2.Canny(image_gray, 100, 150) circle = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1, 80, param1=40, param2=20, minRadius=20, maxRadius=100) if not circle is None: circle = np.uint16(np.around(circle)) for i in circle[0, :]: cv2.circle(image, (i[0], i[1]), i[2], (0, 0, 255), 2) imgs = np.hstack([rawImage,image]) cv2.imshow("image_lines", imgs) cv2.imwrite("test.jpg",imgs) cv2.waitKey(0)
(1)什么是直方图?
直方图就是对一张图上,所有颜色值出现的次数的分布。
代码:
import cv2 import matplotlib.pyplot as plt img = cv2.imread('1.jpg') # img[...,0]=0 # img[...,1]=0 # cv2.imshow("...",img) # img_B = cv2.calcHist([img], [0], None, [256], [0, 256]) # plt.plot(img_B, label='B', color='b') # img_G = cv2.calcHist([img], [1], None, [256], [0, 256]) # plt.plot(img_G, label='G', color='g') # img_R = cv2.calcHist([img], [2], None, [256], [0, 256]) plt.plot(img_R, label='R', color='r') plt.show()
(2)什么是直方图均衡化?
直方图均衡化是一种利用灰度变换自动调节图像对比度质量的方法,基本思想是通过灰度级的概率密度函数求出灰度变换函数,它是一种以累计分布函数变换法为基础的直方图修正法。
代码:
import cv2 import matplotlib.pyplot as plt img = cv2.imread('7.jpg', 0) cv2.imshow("src", img) his = cv2.calcHist([img], [0], None, [255], [0, 255]) plt.plot(his, label='his', color='r') # plt.show() dst = cv2.equalizeHist(img) cv2.imshow("dst", dst) cv2.imwrite("15.jpg", dst) his = cv2.calcHist([dst], [0], None, [255], [0, 255]) plt.plot(his, label='his', color='b') plt.show()
(3)普通的直方图均衡化和自适应直方图均衡化有什么区别?
普通直方图均衡化可以会导致某些局部区域变得非常亮;因此我们希望图片局部进行直方图均衡化。(需要设置局部窗口的大小)
import cv2
img = cv2.imread('8.jpg', 0)
cv2.imshow("src", img)
dst1 = cv2.equalizeHist(img)
cv2.imshow("dst1", dst1)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))# 8*8即局部窗口大小
dst2 = clahe.apply(img)
cv2.imshow("dst2", dst2)
cv2.waitKey(0)
(4)直方图反投影:
利用HSV直方图提取某块颜色(需要有某块区域模板),就可以获取图片上某些区域的掩码。例如,蓝天、草坪……
import cv2 import numpy as np roi = cv2.imread('10.jpg') # 被提取的图片 hsv = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) target = cv2.imread('9.jpg') # 提取颜色的模板 hsvt = cv2.cvtColor(target, cv2.COLOR_BGR2HSV) roihist = cv2.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256]) cv2.normalize(roihist, roihist, 0, 255, cv2.NORM_MINMAX) dst = cv2.calcBackProject([hsvt], [0, 1], roihist, [0, 180, 0, 256], 1) disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) dst = cv2.filter2D(dst, -1, disc) ret, thresh = cv2.threshold(dst, 50, 255, 0) thresh = cv2.merge((thresh, thresh, thresh)) res = cv2.bitwise_and(target, thresh) res = np.hstack((target, thresh, res)) cv2.imshow('img', res) cv2.waitKey(0)
(1)什么是傅里叶变换?
傅里叶变换就是将图像从时域转换为频域,在频域上对图像进行操作。
时域(时间域)——自变量是时间,即横轴是时间,纵轴是信号的变化。其动态信号x(t)是描述信号在不同时刻取值的函数。
频域(频率域)——自变量是频率,即横轴是频率,纵轴是该频率信号的幅度,也就是通常说的频谱图。
(2)频谱图;
(3)代码:
import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread('9.jpg', 0) dft = cv2.dft(np.float32(img), 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.figure(figsize=(10, 10)) plt.subplot(221), plt.imshow(img, cmap='gray') plt.title('Input Image'), plt.xticks([]), plt.yticks([]) plt.subplot(222), plt.imshow(magnitude_spectrum, cmap='gray') plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([]) rows, cols = img.shape crow, ccol = rows // 2, cols // 2 # create a mask first, center square is 1, remaining all zeros mask = np.zeros((rows, cols, 2), np.uint8) mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1 fshift = dft_shift * mask # apply mask and inverse DFT f_ishift = np.fft.ifftshift(fshift) img_back = cv2.idft(f_ishift) img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1]) plt.subplot(223), plt.imshow(img_back, cmap='gray') plt.title('Input Image'), plt.xticks([]), plt.yticks([]) plt.subplot(224), plt.imshow(img_back) plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([]) plt.show()
(1)什么是特征?
特征实质上就是一张图片上突出的地方。也就是会更加吸引我们注意的地方。而对计算机而言,特征就是能够达到目标和解决问题的地方。
(2)Harris角点检测;
dst = cv2.cornerHarris(gary_img, 2, 3, 0.04) # 得到角点位置的掩码图
img[dst>0.01*dst.max()] = [0,0,255]
(3)Shi-Tomasi角点检测:获得最好的角点;
corners = cv2.goodFeaturesToTrack(gray, 100, 0.01, 10)
corners = np.int0(corners)
for i in corners:
x, y = i.ravel()
cv2.circle(img, (x, y), 3, 255, 3)
对于上述两种角点,它们具有旋转不变特性。即即使图片旋转,也能找到角点。但是如果我们对图像近缩放,可能就找不到角点了。
(4)SIFT
sift = cv2.xfeatures2d.SIRF_create() # 有专利保护
kp = sift.detect(gray, None)
img2 = cv2.drawKeypoints(img, kp, None, color=(0,0,255))
(5)SURF:SURF比SIFT快。
suft = cv2.xfeatures2d.SURF_create() # 有专利保护
kp = sift.detect(gray, None)
img2 = cv2.drawKeypoints(img, kp, None, color=(0,0,255))
(6)Fast算法:
fast = cv2.FastFeatureDetector_create(threshold=35)
fast.setNonmaxSuppression(False) # 关闭非极大值抑制
kp = fast.detect(grayImg, None)
img2 = cv2.drawKeypoints(img, kp, None, color=(0,0,255))
(7)ORB算法:ORB是FAST和BRIEF的合体。
orb = cv2.ORB_create()
kp = orb.detect(grayImg, None)
kp, des = orb.compute(grayImg, kp)
img2 = cv2.drawKeypoints(img, kp, None, color=(0,0,255), flags=0)
(8)特征匹配
FLANN匹配器:匹配两张图上的角点位置。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。