使用 OpenCV 进行图像处理简介

本文介绍了如何使用OpenCV进行图像处理,包括灰阶转换、二值化、图像旋转、堆叠显示、轮廓提取和覆盖技术。通过实例展示了如何在Python环境中设置OpenCV,以及如何对图像进行预处理和操作,以实现图像分析的基础步骤。

IDE 和环境的选择取决于你,我将使用 Spyder。Spyder是一个用 Python 编写的开源 IDE。

让我们从安装相关库开始。OpenCV 有两个库。一个是官方的 OpenCV 库,另一个是我们可以贡献的稍微多变的 OpenCV contrib 库。将安装contrib——以利用更多更新的功能。

首先,让我们创建一个新环境并更改我们的解释器。

用来创建新环境的Anaconda命令:

conda create --name opencvenv python

键入“y”确认后,我们可以激活名为 opencvenv 的环境并使用 pip 下载OpenCV 库。

conda activate opencvenv
pip install opencv-contrib-python
pip install spyder

让我们从Spyder中的工具>首选项>Python 解释器字段中选择我们创建的环境中的Python 解释器。

我们准备开始了。

import cv2

让我们保存下面的图像或找到类似的图像并将其保存在同一目录中。

7d8cdea357f5cf1424633b7ce345bf8b.jpeg

为了将这个名为 logo.png 的图像以新名称 newLogo.png 写入同一目录中,我们可以首先将图像读取为img

img = cv2.imread("logo.png")
cv2.imwrite("yeniLogo.png", img)

为了在不同的窗口中看到徽标,让我们用 imshow 调用该窗口。

我们添加 destroyAllWindows() 函数来退出弹出窗口。

cv2.imshow('logo penceresi', img)

cv2.waitKey(0)
cv2.destroyAllWindows()

灰阶

将讨论两种将 logo 转换为灰度的类似方法。

方法一

使用这种方法,可以通过将图像转换为灰度来直接读取图像。

img = cv2.imread("logo.png", cv2.IMREAD_GRAYSCALE)

方法二

有了这个方法,我们就可以把之前读成img的彩色图片转成灰度图了。这样我们就可以访问两个版本。

img = cv2.imread("logo.png")
grayImg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('logo penceresi', grayImg)

cv2.waitKey(0)
cv2.destroyAllWindows()
aa9e46f2982f283937ed42cbaa9e32f3.jpeg

二值化方法(Binarization)

我们可以将二值化视为将灰度图像变成黑白图像。

我们可以使用一种称为图像阈值化的方法来做到这一点。

在数字图像处理中,阈值化是一种用于分割图像的方法。对图像进行灰度化后,得到二值图像。阈值处理可用于创建二进制图像

通过下面的代码,我们确保我们应用灰度的图像中每个像素为 0 的正方形保持为 0,即黑色,并且将不匹配的像素转换为白色。

ret, thresh = cv2.threshold(grayImg, 0, 255, cv2.THRESH_BINARY)

使用 NumPy 我们可以检查两个图像的唯一值。

grayImg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_np = np.array(grayImg)
print(np.unique(gray_np))

ret, thresh = cv2.threshold(grayImg,0,255, cv2.THRESH_BINARY)
binary_np = np.array(thresh)
print(np.unique(binary_np))
Output:
[  0   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  19  20
  21  23  24  26  27  28  29  30  31  35  36  38  39  41  44  46  47  48
  52  54  56  59  62  65  68  69  72  73  75  76  80  84  86  91 100 105
 106 114 115 120 125 127 135 140 150 151 159 174 181 193 199 214 221 229
 246 251 255]
[  0 255]

在灰度版本中,值的范围从 0 到 255,而在二值化版本中,我们只观察到唯一值 0 和 255。

fda0e87c812538054c7400d380cbd739.jpeg

图像旋转

因为深度学习模型可以用更多的数据进行更好的训练,所以我使用了数据增强。图像旋转可以显着增加数据的数量。

让我们创建沿不同方向旋转的图像副本。

rot1 = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) #örnek
rot2 = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
rot3 = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE)
rot4 = cv2.rotate(img, cv2.ROTATE_180_COUNTERCLOCKWISE)

cv2.imshow('logo penceresi', rot1)
cv2.imshow('logo penceresi', rot2)
cv2.imshow('logo penceresi', rot3)
cv2.imshow('logo penceresi', rot4)
3e7ce3d5bf4282ee4281c528260a63c2.jpeg

例子

  • 为了用NumPy生成随机数据,转换成OpenCV格式显示出来,我们可以在OpenCV中用NumPy default_rng定义随机生成的数字为数组。

from numpy.random import default_rng

img = np.random.default_rng().integers(2, size=(300,300), dtype=np.uint8)
img = np.array(img*255)
cv2.imshow('logo penceresi', img)
2b1a78e82c7ab5a9321667f7781ca216.jpeg

堆叠显示

np.zeros Python 函数用于创建一个用零填充的矩阵。

np.full 用于用我们给出的值填充矩阵。让我们使用它们创建一个白色和黑色图像,并在单独的窗口中检查它们。

image1 = np.zeros((50, 50), np.uint8)
cv2.imshow("siyah görsel", image1)
image2 = np.full((50, 50), 255, np.uint8)
cv2.imshow("beyaz görsel", image2)

垂直查看:

stacked_vertical = np.vstack((image1, image2))
stacked_vertical = np.array(stacked_vertical, np.uint8)
cv2.imshow("Dikey", stacked_vertical)

横向查看:

stacked_horiz = np.hstack((image1, image2))
stacked_horiz = np.array(stacked_horiz, np.uint8)
cv2.imshow("Yatay", stacked_horiz)

轮廓

如果我们能够找到对象的轮廓,我们就可以通过简单的分类来判断这是否是我们要找的对象。

为了进行轮廓提取过程,首先需要进行预处理。为了检测轮廓,必须正确确定背景。如果背景和对象之间的对比度差高,则可以容易地检测到背景和对象。因此,我们尝试通过预处理创建高对比度。

如果我们将图像转换为灰度并将其二值化,如上所示,我们就完成了预处理。

我们可以通过指定轮廓之间的关系和提取轮廓时要使用的方法来提取轮廓的值。

contour, h = cv2.findContours(thresh, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)

为了绘制带有轮廓的图像,我们可以使用下面的代码,通过给出我们想要绘制轮廓的图像的值——设为 -1 ,来获取整个索引,( 255, 0, 255) 指定轮廓线的颜色,值 1 指定线条的粗细。

cv2.drawContours(img, contours, -1, (255, 0, 255), 1)

cv2.imshow('logo penceresi', img)
f1a766b9debe5d1ce603474bd1196dc3.jpeg

要在另一幅图像中放置轮廓线,我们需要应用一种稍微不同的方法。

image_list=[]
for i, cnt in enumerate(contours):
    im = np.zeros((img.shape[0], img.shape[1]), np.uint8) #Boş görselin boyutu 
    cv2.drawContours(im, [cnt], -1, (255, 255, 255), -1)
    image_list.append(im)

imtoshow1 = np.hstack((image_list[0:7]))
imtoshow2 = np.hstack((image_list[7:13]))

cv2.imshow('logo penceresi 1', imtoshow1)
cv2.imshow('logo penceresi 2', imtoshow2)
7432cebcdeaaaa8dd88efa5491e22f00.jpegd851b6650de560d2e35036b19cf4f95d.jpeg

覆盖

它是一种用于将图像的某些部分与其他部分区分开来的技术。

425be1c0ab0eb59e6cfc31805926c005.jpeg

如果原始图像中的掩码和像素的值为1,则可以在图像中解析出对象,因为在输出图像中也会得到1的值。

让我们更新一下提取轮廓并访问蒙版图像的代码。

image_list=[]
masked_images=[]
for i, cnt in enumerate(contours):
    area = cv2.contourArea(cnt)
    if area > 25:
        im = np.zeros((img.shape[0], img.shape[1]), np.uint8)  
        cv2.drawContours(im, [cnt], -1, (255, 255, 255), -1)
        image_list.append(im)
        
        masked = cv2.bitwise_and(img, img, mask=im)
        masked_images.append(masked)

bound1 = int(len(image_list)/2)
bound2 = len(image_list) +1

imtoshow1 = np.hstack((masked_images[0 : bound1]))
imtoshow2 = np.hstack((masked_images[bound1 : bound2]))
7e6b54bce82a84a927a47b34a5b1a85f.jpeg

如果我们想一个一个地保存字母,在for循环的末尾添加下面的代码就可以了。

cv2.imwrite("letter"+str(i)+".jpg", masked)

上个月,我对自己的照片应用了边缘检测:

1b03321cb21d1778e4ccbed3cada64c2.jpeg

感谢阅读!

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

3f90a26d0849925d0cf9bc35949d2ade.jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值