1. 磐创AI首页
  2. Medium

了解OpenCV的第一步-Python

你可以去我的Github账户找到一些入门级项目。我将它们与它们的来源共享,这样您就可以查看它们,并为自己找到更多学习🌈的项目Github account

在我的上一篇文章中,我简要地提到了计算机视觉。计算机视觉背后的所有想法都是计算机可以从数字视频或图像中辨别出来的。这是一个旨在自动化人类视觉可以处理的任务的领域。计算机视觉操作需要一些方法,如图像的处理、分析和提取。我们显然不能给模型提供直接的图像。如你所知,计算机只懂数字,为了训练模型,我们必须将图片转换成矩阵或张量。我们还可以对图像进行更改,以使操作更容易。article

ğŸ“什么是OpenCV库?

OpenCV支持多种编程语言,如Python、C++、Java等。它可以处理图像和视频来识别对象、人脸,甚至是人的笔迹。

在本文中,我将尝试为您提供有关™™图像预处理函数的初学者友好信息。我们将对图片进行剪切、变换、旋转和更改颜色等操作。让?EURO™‘s在ğŸšEURO中潜水。

1.导入OpenCV

import cv2 as cv

2.读取图片

在我们想要对我们的形象做任何事情之前,我们首先需要阅读我们的形象。

img = cv.imread("bojack-horseman.png") # image I choose

据我所知,图像文件的扩展名可以是jpeg或png。实际上我还没有尝试过任何其他的扩展,但是如果你愿意的话,你可以在任何时候用™搜索它!

📌有一件很重要的事情,每次我们完成™代码后,我们都应该将这两行代码添加到文件的末尾:

cv.waitKey(0)
cv.destroyAllWindows()

cv.waitKey(0)将无限显示窗口,直到任何按键。您可以通过按键盘上的任意键来关闭图像窗口,如?EUROURE˜Q?EURE™或ESPECT键。如果您在waitKey中放入任何其他数字,它将等待那么长的毫秒,然后自动关闭。

cv.delestroyAllWindows()只是销毁我们创建的所有窗口。

我们读取我们的图像,现在我们应该这样显示它:

cv.imshow("Image", img)

代码的最终版本:

import cv2 as cv

输出:

如果您想要在灰度模式下读取图像,只需添加一个零即可。

img = cv.imread("bojack-horseman.png", 0)

3.在图像中绘制形状和书写文本

使用NumPy创建黑色图像:

import numpy as np

让?Euro™‘s将图像打印为绿色:

blank[:] = 0, 255, 0 # green
cv.imshow("Green", blank)

输出:

绘制一个矩形:

cv.rectangle(img, (0,0), (250,250), (0, 250, 0), thickness = cv.FILLED)
cv.imshow("Rectangle", blank)

输出:

第一个参数是我们要在其上绘制矩形的图像,第二个参数是矩形的起点,第三个参数是en点,第四个参数是颜色,将其作为元组传递,第五个参数是矩形的粗细-在这里我们将其作为cv.FILLED传递,它的意思是填充形状,您可以将-1传递到相同的目的。

画一个圆:

cv.circle(blank, (250, 250), 40, (0, 0, 255), thickness = 3)

第一个我们要画的图像,第二个是圆形-™的中心坐标,半径是它半径的三十分之一,第四个是它的颜色,第五个是它的厚度,这次我们不想填充™的形状。

画一条线:

cv.line(blank, (0, 0), (250, 250), (255, 250, 255), thickness = 3)

我们要在其上绘制的第一个图像是,第二行是™的起始坐标,第三行是™的结束坐标,第四行是它的颜色,第五行是它的厚度。

在图像上写入文本:

cv.putText(blank, "Geronimo", (0, 255), cv.FONT_HERSHEY_TRIPLEX, 1.0, (0, 255, 0), 2, cv.LINE_AA)

第一个参数是相同的,第二个参数是图片的位置,第三个参数是字体大小,你可以在这里自己选择,第四个参数是字体比例,第五个是颜色,第六个是粗细,为了看起来更好,OpenCV推荐LINE_AA。here

4.图像的几何变换

OpenCV有两个变换函数:cv.warpAffine和cv.warpVision。cv.warpAffine函数以2×3矩阵为输入,cv.wrapVision函数以3×3矩阵为输入。

调整图像大小:

它只是简单地调整图像的大小。函数也非常向前,cv.resize()。可以指定新尺寸,也可以指定比例因子。

height, width = img.shape[:2]
resized = cv.resize(img, (2*width, 2*height), cv.INTER_LINEAR)
cv.imshow("resized", resized)

第三个参数是插值方法。

OpenCV库中有不同类型的插补方法。较佳的插值方法是用于收缩的cv.INTER_AREA和用于缩放的cv.INTER_CUB立方(慢速)&cv.INTER_LINEAR。默认情况下,插值方法cv.INTER_LINEAR用于所有调整大小的目的。cv.INTER_AREA cv.INTER_CUBIC cv.INTER_LINEAR cv.INTER_LINEAR

转型

您可以移动对象-™的位置。

可以将x和y方向的变换值转换为NumPy数组,然后将其传递给cv.wrapAffine()函数。以下示例针对(100,50)Shift:

rows, cols = img.shape
M = np.float32([[1,0,100], [0,1,50]]) # marked
trans = cv.warpAffine(img, M, (cols,rows)) # 3rd is the size of the # output image
cv.imshow("Transformated", trans)


转换矩阵定义为(标记代码行原因):

ğŸ“�cv.warpAffine()函数的第三个参数是输出图像的大小,其格式应为(Width,Height)。请记住,宽度等于列数,高度等于行数。cv.warpAffine()

旋转

OpenCV提供具有可调整旋转中心的缩放旋转,以便您可以在您喜欢的任何位置旋转。修改后的变换矩阵由下式给出:

其中:

?=比例-<…因为很遗憾, ²=比例-<…我是罪人。 为了找到这个转换矩阵,OpenCV提供了一个函数cv.getRotationMatrix2D。下面的示例将图像相对于中心旋转90度,不进行任何缩放:cv.getRotationMatrix2D

M = cv.getRotationMatrix2D(((cols-1)/2.0, (rows-1)/2.0), 90, 1)
rotated = cv.warpAffine(img, M, (cols, rows))
cv.imshow("Rotated", rotated)

5.图像阈值化

对于每个像素,应用相同的阈值。如果像素值小于阈值,则将其设置为0,否则将其设置为最大值。函数cv.Threshold用于应用阈值。第一个参数是源图像,它应该是灰度图像。第二个参数是用于对像素值进行分类的阈值。第三个参数是分配给超过阈值的像素值的最大值。OpenCV提供了不同类型的阈值,该阈值由函数的第四个参数给出。如上所述的基本阈值是通过使用类型cv.THRESH_BINARY来完成的。cv.threshold cv.THRESH_BINARY

该方法返回两个输出。第一个是使用的阈值,第二个输出是阈值图像。

# binarizing the image, 0 --> black, above (255) --> white
ref, thresh = cv.threshold(gray, 125, 255, cv.THRESH_BINARY)
cv.imshow("thresh", thresh)

6.模糊处理

图像模糊是通过将图像与低通过滤内核卷积实现的。它对消除噪音很有用。它实际上从图像中删除了高频内容。所以在这个操作中,边缘会有点模糊(还有一些模糊技术不会™模糊边缘)。

高斯模糊

用高斯函数模糊图像。高斯过滤采用像素周围的邻域,并找到其高斯加权平均。

我们应该指定果仁的宽度和高度。给出零的第三个自变量表示x、y方向上的标准偏差,将根据核大小计算xSigma和ySigma。或者您可以指定它。

blur = cv.GaussianBlur(img, (5,5), cv.BORDER_DEFAULT)


双边滤波

在大多数模糊技术中,边缘也是模糊的,但是双边滤波在去除噪声的同时保持边缘的锐化。缺点是,与其他模糊技术相比,这种操作速度较慢。

blur = cv.bilateralFilter(img,9,75,75)

7.精明边缘检测

边缘检测有多个阶段,我将逐一进行™。

步骤1:

首先,我们应该使用5×5高斯过滤(高斯模糊)去除图像中的噪声,因为这一操作对噪声敏感。

步骤2:

然后对平滑后的图像分别进行水平方向和垂直方向的Sobel核滤波,得到水平方向(Gx)和垂直方向(Gy)的一阶导数。利用这两幅图像,我们可以找到每个像素的边缘梯度和方向。

ğŸ“�渐变方向始终垂直于边。它被舍入为代表垂直、水平和两个对角方向的四个角度之一。

步骤3:

在这一步中,检查每个像素在其梯度方向的邻域内是否为局部最大值。

与上图一样,A点位于边缘,B点和C点位于渐变方向。检查一个点是否为其邻域的局部最大值。如果它被考虑到下一阶段,如果不是,它被抑制到零。

步骤4:

最后一步是确定选定的边是否真的是边。为此,我们需要一个阈值、minVal和maxVal。强度梯度大于maxVal的边被视为确定边,小于minVal的边被视为非边。位于这两条线之间的那些,根据它们与确定边的连通性进行分类,以及非边。

点位于maxVal之上,因此它被归类为确定边。

B点介于两者之间,与确定边无关,属于非边。

C点介于两者之间,并且与确定边A点有联系,它被归类为确定边。

canny = cv.Canny(img, 125, 175)


第一个参数是我们的输入图像。第二个和第三个参数分别是minVal和maxVal。第三个参数是AIRATION_SIZE。它是用于查找图像渐变的Sobel内核的大小(默认情况下为3)。

8.直方图

直方图可以让您对强度分布有一个整体的了解。在x轴上有从0到255的像素值(非强制),在y轴上图像中有相应数量的像素值。

gray_hist = cv.calcHist([img], [0], None, [256], [0, 256])
plt.figure()


第一个参数是我们想要看到的图像的直方图,应该放在方括号中。第二个参数是通道,应该放在方括号中,我们给了0,因为我们的图像是灰度的。您可以根据您的形象进行更改。第三个参数是蒙版图像。如果你想要看到整个图像的分布,请不要像我这样做,但是如果你想要找到一个图像的特定区域,你必须创建一个蒙版图像。第四个参数是histSize,它代表我们的BIN计数。第五个参数是范围。我给出了正常范围。

上面的大多数定义来自OpenCVâuro™的文档。他们的文档非常棒,您甚至不需要寻找其他站点即可理解™。你绝对应该去看看。这只是个开始。对于我上面提到的所有内容,我建议您观看两个教程视频,以及更多内容:

你可以去我的Github账户找到一些入门级项目。我将它们与它们的来源共享,这样您就可以查看它们,并为自己找到更多学习🌈的项目Github account

在另一篇文章中再见!

参考文献

https://sisu.ut.ee/imageprocessing/book/3https://sisu.ut.ee/imageprocessing/book/3

原创文章,作者:fendouai,如若转载,请注明出处:https://panchuang.net/2021/07/02/%e4%ba%86%e8%a7%a3opencv%e7%9a%84%e7%ac%ac%e4%b8%80%e6%ad%a5-python/

联系我们

400-800-8888

在线咨询:点击这里给我发消息

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息