史上最全的OpenCV⼊门教程
⼀、Python OpenCV ⼊门
欢迎阅读系列教程,内容涵盖 OpenCV,它是⼀个图像和视频处理库,包含 C ++,C,Python 和 Java 的绑定。 OpenCV ⽤于各种图像和视频分析,如⾯部识别和检测,车牌阅读,照⽚编辑,⾼级机器⼈视觉,光学字符识别等等。
你将需要两个主要的库,第三个可选:python-OpenCV,Numpy 和 Matplotlib。
Windows ⽤户:
python-OpenCV:有其他的⽅法,但这是最简单的。 下载相应的 wheel(.whl)⽂件,然后使⽤pip进⾏安装。 观看视频来寻求帮助。pip install numpypip install matplotlib
不熟悉使⽤pip? 请参阅pip安装教程来获得帮助。
Linux/Mac ⽤户
pip3 install numpy
或者
apt-get install python3-numpy
你可能需要apt-get来安装python3-pip。
pip3 install matplotlib
或者
apt-get install python3-matplotlibapt-get install python-OpenCV
Matplotlib 是⽤于展⽰来⾃视频或图像的帧的可选选项。 我们将在这⾥展⽰⼏个使⽤它的例⼦。 Numpy 被⽤于“数值和 Python”的所有东西。 我们主要利⽤ Numpy 的数组功能。 最后,我们使⽤python-OpenCV,它是 Python 特定的 OpenCV 绑定。
OpenCV 有⼀些操作,如果没有完整安装 OpenCV (⼤⼩约 3GB),你将⽆法完成,但是实际上你可以⽤ python-OpenCV 最简安装。我们将在本系列的后续部分中使⽤ OpenCV 的完整安装,如果你愿意的话,你可以随意获得它,但这三个模块将使我们忙碌⼀段时间!
通过运⾏ Python 并执⾏下列命令来确保你安装成功:
import cv2import matplotlibimport numpy
如果你没有错误,那么你已经准备好了。好了嘛?让我们下潜吧!
⾸先,在图像和视频分析⽅⾯,我们应该了解⼀些基本的假设和范式。对现在每个摄像机的记录⽅式来说,记录实际上是⼀帧⼀帧地显⽰,每秒 30-60 次。但是,它们的核⼼是静态帧,就像图像⼀样。因此,图像识别和视频分析⼤部分使⽤相同的⽅法。有些东西,如⽅向跟踪,将需要连续的图像(帧),但像⾯部检测或物体识别等东西,在图像和视频中代码⼏乎完全相同。
接下来,⼤量的图像和视频分析归结为尽可能简化来源。这⼏乎总是起始于转换为灰度,但也可以是彩⾊滤镜,渐变或这些的组合。从这⾥,我们可以对来源执⾏各种分析和转化。⼀般来说,这⾥发⽣的事情是转换完成,然后是分析,然后是任何覆盖,我们希望应⽤在原始来源上,这就是你可以经常看到,对象或⾯部识别的“成品”在全⾊图像或视频上显⽰。然⽽,数据实际上很少以这种原始形式处理。有⼀些我们可以在基本层⾯上做些什么的例⼦。所有这些都使⽤基本的⽹络摄像头来完成,没有什么特别的:
背景提取
颜⾊过滤
边缘检测
⽤于对象识别的特征匹配
⼀般对象识别
在边缘检测的情况下,⿊⾊对应于(0,0,0)的像素值,⽽⽩⾊线条是(255,255,255)。视频中的每个图⽚和帧都会像这样分解为像素,并且像边缘检测⼀样,我们可以推断,边缘是基于⽩⾊与⿊⾊像素对⽐的地⽅。然后,如果我们想看到标记边缘的原始图像,我们记录下⽩⾊像素的所有坐标位置,然后在原始图像或视频上标记这些位置。
到本教程结束时,你将能够完成上述所有操作,并且能够训练你的机器识别你想要的任何对象。就像我刚开始说的,第⼀步通常是转换为灰度。在此之前,我们需要加载图像。因此,我们来做吧!在整个教程中,我极⼒⿎励你使⽤你⾃⼰的数据来玩。如果你有摄像头,⼀定要使⽤它,否则到你认为很有趣的图像。如果你有⿇烦,这是⼀个⼿表的图像:
import cv2import numpy as npfrom matplotlib import pyplot as pltimg =
cv2.imread('watch.jpg',cv2.IMREAD_GRAYSCALE)cv2.imshow('image',img)cv2.waitKey(0)cv2.destroyAllWindows()
⾸先,我们正在导⼊⼀些东西,我已经安装了这三个模块。接下来,我们将img定义为ad(image file, parms)。默认值是
IMREAD_COLOR,这是没有任何 alpha 通道的颜⾊。如果你不熟悉,alpha 是不透明度(与透明度相反)。如果你需要保留 Alpha 通道,也可以使⽤IMREAD_UNCHANGED。很多时候,你会读取颜⾊版本,然后将其转换为灰度。如果你没有⽹络摄像机,这将是你在本教程中使⽤的主要⽅法,即加载图像。
你可以不使⽤IMREAD_COLOR ...等,⽽是使⽤简单的数字。你应该熟悉这两种选择,以便了解某个⼈在做什么。对于第⼆个参数,可以使⽤-1,0或1。颜⾊为1,灰度为0,不变为-1。因此,对于灰度,可以执⾏cv2.imread('watch.jpg', 0)。
⼀旦加载完成,我们使⽤cv2.imshow(title,image)来显⽰图像。从这⾥,我们使⽤cv2.waitKey(0)来等待,直到有任何按键被按下。⼀旦完成,我们使⽤cv2.destroyAllWindows()来关闭所有的东西。
正如前⾯提到的,你也可以⽤ Matplotlib 显⽰图像,下⾯是⼀些如何实现的代码:
import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread('watch.jpg',cv2.IMREAD_GRAYSCALE)plt.imshow(img, cmap = 'gray', interpolation = 'bic
ubic')icks([]), icks([]) # to hide tick values on X and Y axisplt.plot([200,300,400],[100,200,300],'c', linewidth=5)plt.show()
运维是不是超过35岁就不要请注意,你可以绘制线条,就像任何其他 Matplotlib 图表⼀样,使⽤像素位置作为坐标的。 不过,如果你想绘制你的图⽚,Matplotlib 不是必需的。 OpenCV 为此提供了很好的⽅法。 当你完成修改后,你可以保存,如下所⽰:
cv2.imwrite('watchgray.png',img)
将图⽚导⼊ OpenCV 似乎很容易,加载视频源如何? 在下⼀个教程中,我们将展⽰如何加载摄像头或视频源。
⼆、加载视频源
在这个 Python OpenCV 教程中,我们将介绍⼀些使⽤视频和摄像头的基本操作。 除了起始⾏,处理来⾃视频的帧与处理图像是⼀样的。我们来举例说明⼀下:
import numpy as npimport cv2cap = cv2.VideoCapture(0) while(True): ret, frame = ad() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',gray) if cv2.waitKey(1) & 0xFF == ord('q'): lease()cv2.destroyAllWindows()
⾸先,我们导⼊numpy和cv2,没有什么特别的。 接下来,我们可以cap = cv2.VideoCapture(0)。 这将从你计算机上的第⼀个⽹络摄像头返回视频。 如果你正在观看视频教程,你将看到我正在使⽤1,因为我的第⼀个摄像头正在录制我,第⼆个摄像头⽤于实际的教程源。
while(True): ret, frame = ad()
这段代码启动了⼀个⽆限循环(稍后将被break语句打破),其中ret和frame被定义为ad()。 基本上,ret是⼀个代表是否有返回的布尔值,frame是每个返回的帧。 如果没有帧,你不会得到错误,你会得到None。
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
在这⾥,我们定义⼀个新的变量gray,作为转换为灰度的帧。 注意这个BGR2GRAY。 需要注意的是,OpenCV 将颜⾊读取为 BGR(蓝绿⾊红⾊),但⼤多数计算机应⽤程序读取为 RGB(红绿蓝)。 记住这⼀点。
cv2.imshow('frame',gray)
请注意,尽管是视频流,我们仍然使⽤imshow。 在这⾥,我们展⽰了转换为灰⾊的源。 如果你想同时显⽰,你可以对原始帧和灰度执⾏imshow,将出现两个窗⼝。
if cv2.waitKey(1) & 0xFF == ord('q'): break
这个语句每帧只运⾏⼀次。 基本上,如果我们得到⼀个按键,那个键是q,我们将退出while循环,然后运⾏:
这将释放⽹络摄像头,然后关闭所有的imshow()窗⼝。python入门教程2
在某些情况下,你可能实际上需要录制,并将录制内容保存到新⽂件中。 以下是在 Windows 上执⾏此操作的⽰例:
import numpy as npimport cv2cap = cv2.VideoCapture(1)fourcc = cv2.VideoWriter_fourcc(*'XVID')out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))while(True): ret, frame = ad() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) out.write(frame) cv2.imshow('frame',gray) if
cv2.waitKey(1) & 0xFF == ord('q'): lease()lease()cv2.destroyAllWindows()
这⾥主要要注意的是正在使⽤的编解码器,以及在while循环之前定义的输出信息。 然后,在while循环中,我们使⽤out.write()来输出帧。最后,在while循环之外,在我们释放摄像头之后,我们也释放out。
太好了,现在我们知道如何操作图像和视频。 如果你没有⽹络摄像头,你可以使⽤图像甚⾄视频来跟随教程的其余部分。 如果你希望使⽤视频⽽不是⽹络摄像头作为源,则可以为视频指定⽂件路径,⽽不是摄像头号码。
现在我们可以使⽤来源了,让我们来展⽰如何绘制东西。 此前你已经看到,你可以使⽤ Matplotlib 在图⽚顶部绘制,但是 Matplotlib 并不真正⽤于此⽬的,特别是不能⽤于视频源。 幸运的是,OpenCV 提供了⼀些很棒的⼯具,来帮助我们实时绘制和标记我们的源,这就是我们将在下⼀个教程中讨论的内容。
三、在图像上绘制和写字
在这个 Python OpenCV 教程中,我们将介绍如何在图像和视频上绘制各种形状。 想要以某种⽅式标记检测到的对象是相当普遍的,所以我们⼈类可以很容易地看到我们的程序是否按照我们的希望⼯作。 ⼀个例⼦就是之前显⽰的图像之⼀:
对于这个临时的例⼦,我将使⽤下⾯的图⽚:
⿎励你使⽤⾃⼰的图⽚。 像往常⼀样,我们的起始代码可以是这样的:
import numpy as npimport cv2img = cv2.imread('watch.jpg',cv2.IMREAD_COLOR)
matlab安装需要dvd2
下⾯,我们可以开始绘制,这样:
cv2.line(img,(0,0),(150,150),(255,255,255),15)cv2.imshow('image',img)cv2.waitKey(0)cv2.destroyAllWindows()
cv2.line()接受以下参数:图⽚,开始坐标,结束坐标,颜⾊(bgr),线条粗细。
结果在这⾥:
好吧,很酷,让我们绘制更多形状。 接下来是⼀个矩形:
这⾥的参数是图像,左上⾓坐标,右下⾓坐标,颜⾊和线条粗细。
圆怎么样?
cv2.circle(img,(100,63), 55, (0,255,0), -1)
这⾥的参数是图像/帧,圆⼼,半径,颜⾊和。 注意我们粗细为-1。 这意味着将填充对象,所以我们会得到⼀个圆。
线条,矩形和圆都很酷,但是如果我们想要五边形,⼋边形或⼗⼋边形? 没问题!
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)# OpenCV documentation had this code, which reshapes the array to a 1 x 2. I did not # find this necessary, but you may:#pts = shape((-1,1,2))cv2.polylines(img, [pts], True, (0,255,255), 3)
⾸先,我们将坐标数组称为pts(点的简称)。 然后,我们使⽤cv2.polylines来画线。 参数如下:绘制的对象,坐标,我们应该连接终⽌的和起始点,颜⾊和粗细。
你可能想要做的最后⼀件事是在图像上写字。 这可以这样做:
font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(img,'OpenCV Tuts!',(0,130), font, 1, (200,255,155), 2, cv2.LINE_AA)
⽬前为⽌的完整代码:
servlet生命周期中容器只调用一次
java多线程练习题import numpy as npimport cv2img = cv2.imread('watch.jpg',cv2.IMREAD_COLOR)cv2.line(img,(0,0),
(200,300),(255,255,255),angle(img, (500,250),(1000,500),(0,0,255),15)cv2.circle(img,(447,63), 63, (0,255,0), -1)pts = np.array([[100,50],[200,300],[700,200],[500,100]], np.int32)pts = shape((-1,1,2))cv2.polylines(img, [pts], True, (0,255,255), 3)font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(img,'OpenCV Tuts!',(10,500), font, 6, (200,255,155), 13, cv2.LINE_AA)cv2.imshow('image',img)cv2.waitKey(0)cv2.destroyAllWindows()
结果:
在下⼀个教程中,我们将介绍我们可以执⾏的基本图像操作。
四、图像操作
在 OpenCV 教程中,我们将介绍⼀些我们可以做的简单图像操作。 每个视频分解成帧。 然后每⼀帧,就像⼀个图像,分解成存储在⾏和列中的,帧/图⽚中的像素。 每个像素都有⼀个坐标位置,每个像素都由颜⾊值组成。 让我们列举访问不同的位的⼀些例⼦。
我们将像往常⼀样读取图像(如果可以,请使⽤⾃⼰的图像,但这⾥是我在这⾥使⽤的图像):
import cv2import numpy as npimg = cv2.imread('watch.jpg',cv2.IMREAD_COLOR)
现在我们可以实际引⽤特定像素,像这样:
px = img[55,55]
下⾯我们可以实际修改像素:
img[55,55] = [255,255,255]
html阅读器之后重新引⽤:
px = img[55,55]print(px)
现在应该不同了,下⾯我们可以引⽤ ROI,图像区域:
px = img[100:150,100:150]print(px)
我们也可以修改 ROI,像这样:
img[100:150,100:150] = [255,255,255]
我们可以引⽤我们的图像的特定特征:
print(img.shape)print(img.size)print(img.dtype)
我们可以像这样执⾏操作:
watch_face = img[37:111,107:194]img[0:74,0:87] = watch_facecv2.imshow('image',img)cv2.waitKey(0)cv2.destroyAllWindows()
这会处理我的图像,但是可能不能⽤于你的图像,取决于尺⼨。这是我的输出:
这些是⼀些简单的操作。 在下⼀个教程中,我们将介绍⼀些我们可以执⾏的更⾼级的图像操作。
五、图像算术和逻辑运算
欢迎来到另⼀个 Python OpenCV 教程,在本教程中,我们将介绍⼀些简单算术运算,我们可以在图像上执⾏的,并解释它们的作⽤。 为此,我们将需要两个相同⼤⼩的图像来开始,然后是⼀个较⼩的图像和⼀个较⼤的图像。 ⾸先,我将使⽤:
⾸先,让我们看看简单的加法会做什么:
import cv2import numpy as np# 500 x 250img1 = cv2.imread('3D-Matplotlib.png')img2 = cv2.imread('mainsvmimage.png')add =
img1+img2cv2.imshow('add',add)cv2.waitKey(0)cv2.destroyAllWindows()
结果:
你不可能想要这种混乱的加法。 OpenCV 有⼀个“加法”⽅法,让我们替换以前的“加法”,看看是什么:
add = cv2.add(img1,img2)
结果:
这⾥可能不理想。 我们可以看到很多图像是⾮常“⽩⾊的”。 这是因为颜⾊是 0-255,其中 255 是“全亮”。 因此,例如:
(155,211,79) + (50, 170, 200) = 205, 381, 转换为(205, 255,255)。
接下来,我们可以添加图像,并可以假设每个图像都有不同的“权重”。 这是如何⼯作的:
import cv2import numpy as npimg1 = cv2.imread('3D-Matplotlib.png')img2 = cv2.imread('mainsvmimage.png')weighted = cv2.addWeighted(img1, 0.6, img2, 0.4, 0)cv2.imshow('weighted',weighted)cv2.waitKey(0)cv2.destroyAllWindows()
对于addWeighted⽅法,参数是第⼀个图像,权重,第⼆个图像,权重,然后是伽马值,这是⼀个光的测量值。 我们现在就把它保留为零。
这些是⼀些额外的选择,但如果你真的想将⼀个图像添加到另⼀个,最新的重叠在哪⾥? 在这种情况下,你会从最⼤的开始,然后添加较⼩的图像。 为此,我们将使⽤相同的3D-Matplotlib.png图像,但使⽤⼀个新的 Python 标志:
现在,我们可以选取这个标志,并把它放在原始图像上。 这很容易(基本上使⽤我们在前⼀个教程中使⽤的相同代码,我们⽤⼀个新的东西替换了图像区域(ROI)),但是如果我们只想要标志部分⽽不是⽩⾊背景呢? 我们可以使⽤与之前⽤于 ROI 替换相同的原理,但是我们需要⼀种⽅法来“去除”标志的背景,使得⽩⾊不会不必要地阻挡更多背景图像。 ⾸先我将显⽰完整的代码,然后解释:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。