仿射变换和透视变换是一些更为一般的处理过程中的特殊例子,本质上这两种变换有着相似的特性:他们把原图像的像素从一个地方映射到目标图像的另一个地方。本节讲述通用的变换。
实现极坐标和直角坐标之间相互转换的函数:cv2.cartToPolar()、cv2.polarToCart()
将直角坐标映射为极坐标,cv2.cartToPolar输入参数为x,y,输出为向量的大小和角度值
mag, ang = cv2.cartToPolar(x, y, angleInDegrees=None)
参数 | 含义 |
---|---|
x | x坐标数组; 它必须是单精度或双精度浮点数组。 |
y | y坐标数组,该数组的大小和类型必须与x相同。 |
angleInDegrees=None | 设为True时,角度值以角度[0,360]保存 |
返回值 | 含义 |
---|---|
mag | 向量值大小矩阵 |
ang | 角度值矩阵,角度是通过atan2(y,x)计算的 |
import cv2
path = r"D:\Project\Opencv\Learning01\angelababy2.jpg"
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = gray / 255.0 #像素值0-1之间
#sobel算子分别求出gx,gy
gx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)#x方向的导数
gy = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)#y方向的导数
"""直角坐标系转换为极坐标系"""
mag, ang = cv2.cartToPolar(gx, gy, angleInDegrees=1) #得到梯度幅度和梯度角度阵列
cv2.imshow('gray',gray)
cv2.imshow("mag", mag)
cv2.imshow(" ang", ang)
cv2.waitKey(0)
极坐标反向映射为直角坐标,它的函数同cv2.cartToPolar()相似,区别在于,输入参数为向量的大小和角度值,元素x,y作为返回结果。
x, y = cv2.polarToCart(magnitude, angle, angleInDegrees=None)
参数 | 含义 |
---|---|
magnitude | 向量值大小 |
angle | 角度值 |
angleInDegrees=None | 设为True时,角度值以角度[0,360]保存 |
import cv2
path = r"D:\Project\Opencv\Learning01\fang.png"
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = gray / 255.0 #像素值0-1之间
#sobel算子分别求出gx,gy
gx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)#x方向的导数
gy = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)#y方向的导数
#直角坐标系转换为极坐标系
mag, ang = cv2.cartToPolar(gx, gy, angleInDegrees=1) #得到梯度幅度和梯度角度阵列
"""极坐标转换为直角坐标"""
x,y=cv2.polarToCart(mag,ang)
cv2.imshow("mag", mag)
cv2.imshow(" ang", ang)
cv2.imshow("x", x)
cv2.imshow("y", y)
cv2.waitKey(0)
对于二维图像,对数-极坐标变换,是从直角变换为对数极坐标,既:
对数-极坐标变换的灵感来源于人类视觉系统。注意观察,大小不同的方形图在对数-极坐标系中log®的值不同,方向不同的方形图在对数-极坐标系中theta值不同。
dst= cv2.logPolar(src, center, M, flags)
参数 | 含义 |
---|---|
src | 原图像 |
center | 对数-极坐标变换的中心点 |
M | 比例因子,设置的原则是,便于最感兴趣的特征能够存于图像的大部分区域 |
flags | 不同的插入方式,可以选择cv2.WARP_FILL_OUTLINERS或cv2.INTER_LINEAR或两者都选。 |
通常用来纠正校准的立体图像。用于常规图像重绘。将一幅图像内的像素点放置到另外一幅图像内的指定位置即为重映射
dst= cv2.remap(src, map1, map2, interpolation, borderMode=None, borderValue=None)
参数 | 含义 |
---|---|
src | 原图像 |
map1 | 1.表示(x,y)点的一个映射2.表示CV _16SC2 , CV_32FC1 ,CV_32FC2类型(x,y)点的x值 |
map1 | 1.当map1表示(x,y)时,该值为空2.当map1表示(x,y)点的x值时,该值是CV_16UC1,CV_32FC1类型(x,y)点的y值 |
interpolation | 差值方法 |
borderMode=None | 边界填充方式。 |
borderValue=None | 填充方式为cv2.BORDER_CONSTANT时,填充的值 |
图像常常因为噪声造成破损,图像修复是消除损坏的一种方式,它通过摄取被损坏区域边缘的色彩和纹理,然后传播混合至损坏区域的内部。损坏区域必须不是很‘密集’,并且损坏区域周边残留很多原图像中的纹理和色彩,不能修复那些完全被消除的纹理。
dst= cv2.inpaint(src, inpaintMask, inpaintRadius, flags)
参数 | 含义 |
---|---|
src | 待修复原图像,是一个8位,一维或者三维彩色图像 |
inpaintMask | 是一个8位,与src大小相同的一维图像,且损坏区域被非0像素标记,其他像素被设置为0。它与src具有相同的大小和数量的维度 |
inpaintRadius | 每个已渲染像素周围的区域 |
flags | 支持两种不同的修复方法,cv2.INPAINT_NS和cv2.INPAINT_TELEA |
import cv2
img = cv2.imread('D:\Project\Opencv\Learning03\image01.png')
mask = cv2.imread('D:\Project\Opencv\Learning03\image02.png')
mask=cv2.resize(mask,(225,167))
mask=cv2.cvtColor(mask,cv2.COLOR_BGR2GRAY)
cv2.imshow('img', img)
cv2.imshow('mask', mask)
dst = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)
cv2.imshow('NPAINT_TELEA', dst)
dst2 = cv2.inpaint(img, mask, 3, cv2.INPAINT_NS)
cv2.imshow('INPAINT_NS', dst2)
cv2.waitKey(0)
cv2.destroyAllWindows()
噪声的来源于低光条件的影响。在低光下数字成像器的增益必须增加,结果噪声也被放大,噪声的特征是随机孤立的像素,看起来太亮或者太暗,但在彩色图像中可能发生变色。
经典模糊操作: 许多图像平滑技术,如高斯模糊、中值模糊、均值模糊等,它们在一定程度上可以很好地去除少量的噪声。在这些技术中在一个像素周围取一个小的邻域,然后进行高斯加权平均、中值等操作来替换中心元素。简而言之,一个像素的噪声消除是在它的附近进行的。
FNLMD: 快速非局部均值去噪。思想是在图像中的其他地方寻找类似的像素,再对其取平均值,在这种情况下像素被认为是相似的像素,不是因为它的颜色或强度相似,而是因为它在的环境是相似的(因为许多图像包含重复的结构,因此即使像素被破坏,也会有其他类似的像素)
图像中的蓝色斑块看起来很相似。绿色斑块看起来很相似。所以我们取一个像素,在它周围取一个小窗口,搜索图像中类似的窗口,平均所有窗口,用我们得到的结果替换像素。该方法是一种非局部平均去噪方法。与模糊技术相比,它需要更多的时间,但是它的效果非常好。参考
dst= cv2.fastNlMeansDenoisingColored(src, h=None, hColor=None, templateWindowSize=None, searchWindowSize=None)
参数 | 含义 |
---|---|
src | 彩色原图 |
h=None | 较大的h值可以完美消除噪点,但同时也可以消除图像细节,较小的h值可以保留细节但也可以保留一些噪点 |
hColor=None | 与h相同,但用于颜色分量。 对于大多数图像,等于10的值将足以消除彩色噪点并且不会扭曲颜色 |
templateWindowSize=None | 用于计算权重的模板补丁的像素大小。 应该是奇数。 建议值7 |
searchWindowSize=None | 窗口的像素大小,用于计算给定像素的加权平均值。 应该是奇数的。更大的searchWindowsSize-更长的降噪时间。 建议值21 |
import cv2
'''单个彩色图像的快速非均布均值去噪'''
img = cv2.imread('D:\Project\Opencv\Learning03\image03.png')
dst = cv2.fastNlMeansDenoisingColored(img,10,10,7,21)
cv2.imshow('origin image',img)
cv2.imshow('single gray',dst)
cv2.waitKey(0)
dst= cv2.fastNlMeansDenoising(src, h=None, templateWindowSize=None, searchWindowSize=None)
import cv2
'''单个灰度图像的快速非局部均值去噪'''
img = cv2.imread('D:\Project\Opencv\Learning03\image03.png')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
dst = cv2.fastNlMeansDenoising(gray,10,10,7,21)
cv2.imshow('origin image',gray)
cv2.imshow('single gray',dst)
cv2.waitKey(0)
dst= cv2.fastNlMeansDenoisingMulti(srcImgs, imgToDenoiseIndex, temporalWindowSize, h=None, templateWindowSize=None, searchWindowSize=None)
参数 | 含义 |
---|---|
srcImgs | 图像序列既图像组成的列表,非单个图像。 所有图像应具有相同的类型和大小。 |
imgToDenoiseIndex | 目标图像(想要降噪的图像)在图像序列srcImgs中的索引 |
templateWindowSize | 用于目标图像去噪的周围图像的数量。 |
h=None | 较大的h值可以完美消除噪点,但同时也可以消除图像细节,较小的h值可以保留细节但也可以保留一些噪点 |
templateWindowSize=None | 用于计算权重的模板补丁的像素大小。 应该是奇数。 建议值7 |
searchWindowSize=None | 窗口的像素大小,用于计算给定像素的加权平均值。 应该是奇数的。更大的searchWindowsSize-更长的降噪时间。 建议值21 |
import numpy as np
import cv2
from matplotlib import pyplot as plt
cap = cv2.VideoCapture('D:\Project\Opencv\Learning03\pedestrians.mp4')
img = [cap.read()[1] for i in range(5)]#前5帧图像组层的列表
gray = [cv2.cvtColor(i, cv2.COLOR_BGR2GRAY) for i in img]#把所有的视频帧转换为灰度图像
gray = [np.float64(i) for i in gray]#类型转换为float64
noise = np.random.randn(*gray[1].shape)*10#产生噪声
noisy = [i+noise for i in gray]#将噪声添加到图像
noisy = [np.uint8(np.clip(i,0,255)) for i in noisy]#类型转换为uint8
'''视频灰度图像降噪'''
dst = cv2.fastNlMeansDenoisingMulti(noisy, 2, 5, None, 4, 7, 35)#第3帧降噪(总共5帧)
plt.subplot(132),plt.imshow(noisy[2],'gray')
plt.subplot(133),plt.imshow(dst,'gray')
plt.show()
# cv2.imshow('noisy gray image',noisy[2])
# cv2.imshow('Denoising image',dst)
# cv2.waitKey(0)
与2.2.3类似
dst= cv2.fastNlMeansDenoisingColoredMulti(srcImgs, imgToDenoiseIndex, temporalWindowSize, h=None, hColor=None, templateWindowSize=None, searchWindowSize=None)
参数 | 含义 |
---|---|
srcImgs | 图像序列既图像组成的列表,非单个图像。 所有图像应具有相同的类型和大小。 |
imgToDenoiseIndex | 目标图像(想要降噪的图像)在图像序列srcImgs中的索引 |
templateWindowSize | 用于目标图像去噪的周围图像的数量。 |
h=None | 较大的h值可以完美消除噪点,但同时也可以消除图像细节,较小的h值可以保留细节但也可以保留一些噪点 |
hColor=None | 与h相同,但用于颜色分量。 对于大多数图像,等于10的值将足以消除彩色噪点并且不会扭曲颜色 |
templateWindowSize=None | 用于计算权重的模板补丁的像素大小。 应该是奇数。 建议值7 |
searchWindowSize=None | 窗口的像素大小,用于计算给定像素的加权平均值。 应该是奇数的。更大的searchWindowsSize-更长的降噪时间。 建议值21 |
左侧的图像很差,因为灰度值的范围没有太大的变换,右边的灰度级直方图可以看出这一点。我们处理一个8位图像,强度范围为0-255,但直方图显示实际的灰度值全部聚集在中间附近。直方图均衡是拉伸该范围的方法。
直方图均衡:数学背景是将一个分布(强度值给定的直方图)映射到另一个分布(强度值更宽和理想的均匀分布)。可以使用累积分布函数将原始分布重新映射到均匀分布。
dst= cv2.equalizeHist(src)
import cv2 as cv
def equalHist_demo(image):
''''''
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)#图像转灰度图
'''对比均衡'''
dst=cv.equalizeHist(gray)
cv.imshow('gray', gray)
cv.imshow('equalHist',dst)
src=cv.imread(r'D:\Project\Opencv\Learning01\angelababy.jpg')
equalHist_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()