0717-7821348
浙江11选5爱彩人网

浙江11选5爱彩人网

您现在的位置: 首页 > 浙江11选5爱彩人网
简略人工智能技术运用 运用Python+OpenCV进行图画处理
2019-05-11 23:17:33



图画预处理关简略人工智能技术运用 运用Python+OpenCV进行图画处理于整个图画处理使命来讲特别重要。假如咱们没有进行恰当的预处理,不管咱们有多么好的数据也很难得到抱负的成果。

本篇是视觉入门系列教程的第二篇。整个视觉入门系列内容如下:

了解色彩模型与在图画上制作图形(图画处理根本操作)。

根本的图画处理与滤波技能。

从特征检测到人脸检测。

图画切割与分水岭(Watershed)算法(TBU)

在边际和概括检测中,噪声对检测的精度有很大的影响。因而,去除噪声和操控像素值的巨细能够协助模型聚集于全体特征,取得更高的精度。对应的图画处理技能包括:含糊化(Blurring)、阈值化(thresholding)和形状转化(morphological transformation)。本篇咱们将具体介绍这几个常见的图画预处理技能。(本文假定读者现已了解卷积的概念。)

含糊化(Blurring)

含糊化的方针是完成降噪。咱们有必要分外留意的是:假如咱们把边际检测算法运用到高分辨率的图画上,咱们就会得到许多咱们不感兴趣的检测成果;



相反,假如咱们把图画含糊太多,咱们就会丢掉数据。因而,咱们需求找到一个恰当的含糊量,然后不失掉抱负的边际。

有多种技能用于完成含糊效果,在这儿咱们评论OpenCV中常用的四种技能:均匀含糊(Averaging blurring)、高斯含糊(Gaussian blurring)、中值含糊(median blurring)和双方滤波(bilateral filtering)。这四种技能运用一个一起的根本原理,即运用滤波器(内核)对图画进行卷积运算。不同的是,在四种含糊办法中运用的滤波器的值是不同的。

均匀含糊(Average blurring)是取给定内核(kernel)区域下一切像素值的均匀值替换中心的值。例如,假定给定一个巨细为5X5的内核(kernel),咱们核算卷积成果的均匀值,并将成果放在给定区域的中心。示例如下:



假如咱们添加内核的巨细,像素值将愈加归一化。因而图画也会变得越来越含糊。让咱们用下面的代码比照处理成果。(为了便于比较,将把原始图画加到成果中,进行比照显现。)

# Import the image and convert to RGB

img = cv2.imread('text.jpg')

img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# Plot the image with different kernel sizes

kernels = [5, 11, 17]

fig, axs = plt.subplots(nrows = 1, ncols = 3, figsize = (20, 20))

for ind, s in enumerate(kernels):

img_blurred = cv2.blur(img, ksize = (s, s))

ax = axs[ind]

ax.imshow(img_blurred)

ax.axis('off')

plt.show()



中值含糊(Medium blurring)和均匀含糊(Average blurring)是相同的,仅仅它运用的是中值而不是均匀值。正因为这个特性,当咱们需求处理图画中忽然呈现的噪音时(如“椒盐噪音”),运用中值含糊(medium blurring)的效果要比均匀含糊(average blurring)效果好。



高斯含糊(Gaussian blurring)是运用“值”具有高斯散布的核函数。因为这些值是由高斯函数生成的,因而它的参数需求一个sigma值。如上图,内核的值在接近中心的当地变高,在接近角的当地变小。将该办法运用于具有正态散布的噪声,如白噪声,效果较好。

双方滤波(Bilateral Filtering)是高斯含糊的一个高档版别。含糊化不只能够溶解噪声,并且还会滑润边际。而双方滤波器能在去除噪声的一起坚持边际锐化。这是因为它不只运用高斯散布值,还一起考虑了间隔和像素值的差异。因而,需求指定sigmaSpace和sigmaColor这两个参数。

# Blur the image

img_0 = cv2.blur(img, ksize = (7, 7))

img_1 = cv2.GaussianBlur(img, ksize = (7, 7), sigmaX = 0)

img_2 = cv2.medianBlur(img, 7)

img_3 = cv2.bilateralFilter(img, 7, sigmaSpace = 75, sigmaColor =75)

# Plot the images

images = [img_0, img_1, img_2, img_3]

fig, axs = plt.subplots(nrows = 1, ncols = 4, figsize = (20, 20))

for ind, p in enumerate(images):

ax = axs[ind]

ax.imshow(p)

ax.axis('off')

plt.show()



阈值化(Thresholding)

图画的阈值化是谁呼叫舰队便是运用图画像素点散布规则,设定阈值进行像素点切割,然后得到图画的二值图画。咱们需求设置阈值和最大值,然后据此相应地进行像素值转化。常用的阈值化包括有五种不同的类型:二进制阈值化、反二进制阈值化、阈值化到零、反阈值化到零,和阈值切断。

img = cv2.imread('gradation.png')

# Thresholding

_, thresh_0 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

_, thresh_1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)

_, thresh_2 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)

_, thresh_3 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)

_, thresh_4 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)

# Plot the images

images = [img, thresh_0, thresh_1, thresh_2, thresh_3, thresh_4]

fig, axs = plt.subplots(nrows = 2, ncols = 3, figsize = (13, 13))

for ind, p in enumerate(images):

ax = axs[ind//3, ind%3]

ax.imshow(p)

plt.show()




如上图所示,每种类型的阈值都能够用数学公式表明,I(x, y)是像素点的强度(也称为点(x, y)的像素值)。上图中的图画示例,能够更直观的了解不同阈值化类型之间的差异。

只取一个阈值并将其运用于图画的一切部分并不能满意咱们的悉数需求。假如咱们有一张在多个不同区域亮度差异较多的图片这种状况,将一个值运用于整个图画一般不利于咱们的图画处理使命。其对应更好的办法是对图画的每个部分运用不同的阈值。对应这种状况还有别的一种阈值化技能称为自适应阈值化(Adaptive threshilding)。经过对图画邻域内阈值的核算,能够得到不同光照条件下的较好成果。

# Convert the image to grayscale

img = cv2.imread('text.jpg')

img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Adaptive Thresholding

_, thresh_binary = cv2.threshold(img, thresh = 127, maxval = 255, type = cv2.THRESH_BINARY)

adap_mean_2 = cv2.adaptiveThreshold(img, 255,

cv2.ADAPTIVE_THRESH_MEAN_C,

cv2.THRESH_BINARY, 7, 2)

adap_mean_2_inv = cv2.adaptiveThreshold(img, 255,

cv2.ADAPTIVE_THRESH_MEAN_C,

cv2.THRESH_BINARY_INV, 7, 2)

adap_mean_8 = cv2.adaptiveThreshold(img, 255,

cv2.ADAPTIVE_THRESH_MEAN_C,

cv2.THRESH_BINARY, 7, 8)

adap_gaussian_8 = cv2.adaptiveThreshold(img, 255,

cv2.ADAPTIVE_THRESH_GAUSSIAN_C,

cv2.THRESH_BINARY, 7, 8)

咱们需求将色彩方式转化为灰度来进行自适应阈值化。自适应阈值的参数有maxValue(在上面的示例中设置为255)、adaptiveMethod、thresholdType、blocksize和C。这儿运用的自适应办法有两种:adaptivethresholdmeanc和adaptivethresholdgaussianc。让咱们经过下方代码比照自适应阈值化的不同成果。

# Plot the images

images = [img, thresh_binary, adap_mean_2, adap_mean_2_inv,

adap简略人工智能技术运用 运用Python+OpenCV进行图画处理_mean_8, adap_gaussian_8]

fig, axs = plt.subplots(nrows = 2, ncols = 3, figsize = (15, 15))

for ind, p in enumerate(images):

ax = axs[ind%2, ind//2]

ax.imshow(p, cmap = 'gray')

ax.axis('off')

plt.show()



如上图所示,左面为原始图画与二进制阈值化成果图。比照二进制阈值化成果图与右上方两张成果图(由adaptivethresholdmeanc办法生成)可得,后者生成了更为具体的成果。咱们还能够看出,当C值更大时,图画将变得更显式。C代表从均值或加权均值中减去值的巨细。经过调查上图右子图上下两幅图画,咱们还能够比照检查相同C值下adaptivethreshold meanc和adaptivethreshold _gaussianc两种办法生成的不同效果图。

梯度(Gradient)

在数学中,梯度用于几许地表明多变量函数图形的斜率。因为它是一个向量值函数,代表着方向和巨细两种特点。在这儿,咱们也能够将相同的概念引进到图画的像素值中。图画梯度表明像素强度或色彩方式的方向改变,因而能够经过梯度来定位边际。

# Apply gradient filtering

sobel_x = cv2.Sobel(img, cv2.CV_64F, dx = 1, dy = 0, ksize = 5)

sobel_y = cv2.Sobel(img, cv2.CV_64F, dx = 0, dy = 1, ksize = 5)

blended = cv2.addWeighted(src1=sobel_x, alpha=0.5, src2=sobel_y,

beta=0.5, gamma=0)

laplacian = cv2.Laplacian(img, cv2.CV_64F)

Sobel运算一起运用高斯滑润和微分。咱们经过cv2.Sobel()函数运用它,能够界说两个不同的方向:笔直方向(sobelx)和水平方向(sobely)。dx和dy表明导数。当dx = 1时,经过核算像素值沿水平方向的导数,然后进行图画滤波。

经过函数cv2.addWeighted()对sobelx和sobely的两种过滤器加权求和,能够完成两个方向上的梯度求解及图画滤波。上述代码中两种过滤器设定了相同的权重。

拉普拉斯运算运用的是x和y的二阶导数,数学表达式如下。



让咱们经过下方代码更直观的看看这些处理后图画是什么样的。

# Plot the images

images = [sobel_x, sobel_y, blended, laplacian]

plt.figure(figsize = (20, 20))

for i in range(4):

plt.subplot(简略人工智能技术运用 运用Python+OpenCV进行图画处理1, 4, i+1)

plt.imshow(images[i], cmap = 'gray')

plt.axis('off')

plt.show()



如上图所示,榜首幅和第二幅图画均含有一个方向图样。在榜首张图中,咱们能够清楚地看到笔直方向上的边际。在第二幅图中,咱们能够看到水平线。第三幅和第四幅图画,两个方向的边际都凸显出来了。

形状转化(Morpgological transformations)

经过滤波操作来转化图画的形状的技能称为形状改换(morphological transformation)。首要,让咱们了解下腐蚀(erosion)和扩张(dilation)。

腐蚀(Erosion) 是一种缩小图形形状的技能,通常被运用在灰度图上。过滤器的形状能够是矩形、椭圆和穿插形状。经过过滤器删去给定区域下的悉数0值。



代码完成如下:

img = cv2.imread('simpson.jpg')

# Create erosion kernels

ker简略人工智能技术运用 运用Python+OpenCV进行图画处理nel_0 = np.ones((9, 9), np.uint8)

kernel_1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))

kernel_2 = cv2.getStructuringElement(cv2.MORPH_CROSS, (9, 9))

kernels = [kernel_0, kernel_1, kernel_2]

# Plo简略人工智能技术运用 运用Python+OpenCV进行图画处理t the images

plt.figure(figsize = (20, 20))

for i in range(3):

img_copy = img.copy()

img_copy = cv2.erode(img_copy, kernels[i], iterations = 3)

plt.subplot(1, 3, i+1)

plt.imshow(img_copy)

plt.axis('off')

plt.show()



上图形象的展示出不同滤波器下的不同缩放成果。咱们能够看到三张别离运用根底(方形)滤波器、椭圆形滤波器和穿插滤波器处理过的成果图。能够看出其别离以“圆形”、“线性”和“对角线”的方法进行缩短。

扩张(Dilation)与腐蚀是相反的。它是一种对图形形状进行扩大的操作。其效果也与腐蚀相反。完成代码如下。

# Apply dilation

kernel = np.ones((9, 9), np.uint8)

img_dilate = cv2.dilate(img, kernel, iterations = 3)

plt.figure(figsize = (20, 10))

plt.subplot(1, 2, 1); plt.imshow(img, cmap="gray")

plt.subplot(1, 2, 2); plt.imshow(img_dilate, cmap="gray")

plt.show()



开闭运算是腐蚀和扩张的混合方式。开运算是指先进行腐蚀,然后对腐蚀成果进行扩张操作。相对应的,闭运算是指先进行扩张,再进行腐蚀。



正如上图所示,闭运算一般用于检测图形的全体概括,开运算用于检测图形的子方式(subpatterns)。能够运用函数cv2.morphologyEx()来完成这些操作。参数op用于指定运用哪种运算类型(开/闭)。完好代码如下所示。

# Apply the operations

kernel = np.ones((9, 9), np.uint8)

img_open = cv2.morphologyEx(img, op= cv2.MORPH_OPEN, kernel)

img_close = cv2.morphologyEx(img, op= cv2.MORPH_CLOSE, kernel)

img_grad = cv2.morphologyEx(img, op= cv2.MORPH_GRADIENT, kernel)

img_tophat = cv2.morphologyEx(img, op= cv2.MORPH_TOPHAT, kernel)

img_blackhat = cv2.morphologyEx(img, op= cv2.MORPH_BLACKHAT, kernel)

# Plot the images

images = [img, img_open, img_close, img_grad,

img_tophat, img_blackhat]

fig, axs = plt.subplots(nrows = 2, ncols = 3, figsize = (15, 15))

for ind, p in enumerate(images):

ax = axs[ind//3, ind%3]

ax.imshow(p, cmap = 'gray')

ax.axis('off')

plt.show()



留意,原图中的手在别离运用开闭操作进行处理时会发生不同的成果。梯度滤波(MORPHCGRADIENT)运算是核算扩张成果图与腐蚀成果图之差。顶帽(Top-hat)运算(MORPHTOPHAT)是核算开运算成果图与原始图画之差,黑帽(Black Hot)运算(MORPH_BLACKHAT)是核算闭运算成果图与原始图画之差。形状学运算具体介绍参看(https://homepages.inf.ed.ac.uk/rbf/HIPR2/morops.htm)。

总结与展望

本篇介绍了OpenCV中几项比较常用的运算。下篇将介绍概括检测和人脸检测等检测技能。欢迎批评指正。