【OpenCV】学习OpenCV3——常见的图像变换(2)

一、通用变换

  仿射变换和透视变换是一些更为一般的处理过程中的特殊例子,本质上这两种变换有着相似的特性:他们把原图像的像素从一个地方映射到目标图像的另一个地方。本节讲述通用的变换。

1.1 极坐标映射

  实现极坐标和直角坐标之间相互转换的函数:cv2.cartToPolar()、cv2.polarToCart()

1.1.1 直角坐标转换为极坐标cv2.cartToPolar

  将直角坐标映射为极坐标,cv2.cartToPolar输入参数为x,y,输出为向量的大小和角度值
  mag, ang = cv2.cartToPolar(x, y, angleInDegrees=None)

参数含义
xx坐标数组; 它必须是单精度或双精度浮点数组。
yy坐标数组,该数组的大小和类型必须与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)

在这里插入图片描述

1.1.2 极坐标转换为直角坐标cv2.polarToCart()

  极坐标反向映射为直角坐标,它的函数同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)

在这里插入图片描述

1.2 对数—极坐标映射cv2.LogPlolar()

  对于二维图像,对数-极坐标变换,是从直角变换为对数极坐标,既:
在这里插入图片描述
在这里插入图片描述
  对数-极坐标变换的灵感来源于人类视觉系统。注意观察,大小不同的方形图在对数-极坐标系中log®的值不同,方向不同的方形图在对数-极坐标系中theta值不同。
  dst= cv2.logPolar(src, center, M, flags)

参数含义
src原图像
center对数-极坐标变换的中心点
M比例因子,设置的原则是,便于最感兴趣的特征能够存于图像的大部分区域
flags不同的插入方式,可以选择cv2.WARP_FILL_OUTLINERS或cv2.INTER_LINEAR或两者都选。

1.3 任意映射cv2.remap()

  通常用来纠正校准的立体图像。用于常规图像重绘。将一幅图像内的像素点放置到另外一幅图像内的指定位置即为重映射
  dst= cv2.remap(src, map1, map2, interpolation, borderMode=None, borderValue=None)

参数含义
src原图像
map11.表示(x,y)点的一个映射2.表示CV _16SC2 , CV_32FC1 ,CV_32FC2类型(x,y)点的x值
map11.当map1表示(x,y)时,该值为空2.当map1表示(x,y)点的x值时,该值是CV_16UC1,CV_32FC1类型(x,y)点的y值
interpolation差值方法
borderMode=None边界填充方式。
borderValue=None填充方式为cv2.BORDER_CONSTANT时,填充的值

二、图像修复

2.1 图像修复cv2.inpaint()

  图像常常因为噪声造成破损,图像修复是消除损坏的一种方式,它通过摄取被损坏区域边缘的色彩和纹理,然后传播混合至损坏区域的内部。损坏区域必须不是很‘密集’,并且损坏区域周边残留很多原图像中的纹理和色彩,不能修复那些完全被消除的纹理。
  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()

在这里插入图片描述

2.2 去噪

  噪声的来源于低光条件的影响。在低光下数字成像器的增益必须增加,结果噪声也被放大,噪声的特征是随机孤立的像素,看起来太亮或者太暗,但在彩色图像中可能发生变色。
  经典模糊操作: 许多图像平滑技术,如高斯模糊、中值模糊、均值模糊等,它们在一定程度上可以很好地去除少量的噪声。在这些技术中在一个像素周围取一个小的邻域,然后进行高斯加权平均、中值等操作来替换中心元素。简而言之,一个像素的噪声消除是在它的附近进行的。
  FNLMD: 快速非局部均值去噪。思想是在图像中的其他地方寻找类似的像素,再对其取平均值,在这种情况下像素被认为是相似的像素,不是因为它的颜色或强度相似,而是因为它在的环境是相似的(因为许多图像包含重复的结构,因此即使像素被破坏,也会有其他类似的像素)
在这里插入图片描述

  图像中的蓝色斑块看起来很相似。绿色斑块看起来很相似。所以我们取一个像素,在它周围取一个小窗口,搜索图像中类似的窗口,平均所有窗口,用我们得到的结果替换像素。该方法是一种非局部平均去噪方法。与模糊技术相比,它需要更多的时间,但是它的效果非常好。参考

2.2.1 单彩色图像去噪cv2.fastNlMeansDenoisingColored()

  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)

在这里插入图片描述

2.2.2 单灰度图像去噪cv2.fastNlMeansDenoising()

  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)

在这里插入图片描述

2.2.3 视频灰度图像去噪cv2.fastNlMeansDenoisingMulti()

  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.4 视频彩色图像去噪cv2.fastNlMeansDenoisingColoredMulti()

  与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

三、直方图均衡化cv2.equalizeHist()

在这里插入图片描述
  左侧的图像很差,因为灰度值的范围没有太大的变换,右边的灰度级直方图可以看出这一点。我们处理一个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()

在这里插入图片描述

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Opencv中的分水岭算法(watershed algorithm)是一种自动图像分割算法,常用于分离图像中的前景和背景。下面是使用Opencv中的分水岭算法进行图像分割的步骤: 1. 读入图像并进行预处理,如去噪、灰度化等。 2. 对图像进行二值化处理,得到前景和背景的二值图像。 3. 对二值图像进行距离变换(distance transform),得到每个像素离最近的背景像素的距离。 4. 对距离变换后的图像进行阈值处理,得到图像的分水岭标记(watershed markers)。 5. 对分水岭标记进行修正,确保标记不会重叠或出现空洞。 6. 对分水岭标记应用分水岭算法,得到分割后的图像。 下面是使用Opencv实现分水岭算法的示例代码: ```python import cv2 import numpy as np # 读取图像并进行预处理 img = cv2.imread('input.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) # 进行距离变换 dist_transform = cv2.distanceTransform(thresh,cv2.DIST_L2,5) ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0) # 获取分水岭标记 sure_fg = np.uint8(sure_fg) unknown = cv2.subtract(thresh,sure_fg) ret, markers = cv2.connectedComponents(sure_fg) markers = markers+1 markers[unknown==255] = 0 # 修正分水岭标记 markers = cv2.watershed(img,markers) img[markers == -1] = [255,0,0] # 显示分割结果 cv2.imshow('result', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这段代码中,我们首先读入一张图像并进行预处理,然后进行距离变换,得到每个像素到最近的背景像素的距离。接着使用阈值处理得到分水岭标记,修正分水岭标记并应用分水岭算法,最后显示分割结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值