OpenCV图像处理细节汇总

最近在学习OpenCV中算法的基础知识,发现很多细节,记录下来。

仿射变换和投影变换

仿射变化是图像在二维平面上进行变换,需要三个点的位置就能确定前后变换的模式,就像放在桌子上的一张纸,你只能转,裁剪,不过还有放大和缩小的功能。

投影变换就是三维立体的投影在二维上,需要四个点才能确定变换的模式,好处是可以任意变形了。具体公式如下所示:

![这里写图片描述](https://img-blog.csdn.net/20180530112249210?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xvb3ZlbGo=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

上面主要参考了图像处理的仿射变换与透视变换 ,文中讲的很详细。

双线性差值

双线性差值主要是讲在图像进行放大、缩小时对于新增像素的填充,其中,双线性差值考虑周围四个点的像素值以及距离,从而确定其新增值。
这里写图片描述

看,通过立体图就能形象的感知到黑点的意义了。

特别方便的公式就是矩阵求解

这里写图片描述

同时,具体代码实现时,还有一个小细节,就是对于图像坐标,不能选在坐下家,要选在每个像素中间位置具体讲解

这里写图片描述

int x=(i+0.5)*m/a-0.5

int y=(j+0.5)*n/b-0.5

代替

int x=i*m/a

int y=j*n/b

关于边缘检测

If you want to detect both edges, better option is to keep the output datatype to some higher forms, like cv2.CV_16S, cv2.CV_64F etc, take its absolute value and then convert back to cv2.CV_8U. Below code demonstrates this procedure for a horizontal Sobel filter and difference in results.

就是说梯度检测的时候,CV_8U是只能检测正梯度,而不能保存负梯度,这样很多负梯度,所以要保证用更高精度来实现。

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('box.png',0)

# Output dtype = cv2.CV_8U
sobelx8u = cv2.Sobel(img,cv2.CV_8U,1,0,ksize=5)

# Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U
sobelx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
abs_sobel64f = np.absolute(sobelx64f)
sobel_8u = np.uint8(abs_sobel64f)

plt.subplot(1,3,1),plt.imshow(img,cmap = 'gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(1,3,2),plt.imshow(sobelx8u,cmap = 'gray')
plt.title('Sobel CV_8U'), plt.xticks([]), plt.yticks([])
plt.subplot(1,3,3),plt.imshow(sobel_8u,cmap = 'gray')
plt.title('Sobel abs(CV_64F)'), plt.xticks([]), plt.yticks([])

plt.show()

这里写图片描述

可以看到,在CV_8U精度下,右边边缘没有检测到

猜你喜欢

转载自blog.csdn.net/loovelj/article/details/80508168