使用Python+opencv进行图像处理(一) | 视觉入门
计算机视觉是人工智能最热门的应用领域之一。人工智能技术推动了汽车自动驾驶、机器人以及各种照片处理类软件的巨大发展。目标检测技术也在稳步推进。生成对抗网络(GANs)同样也是人们最近比较关注的一个问题。这些都在向我们展示未来计算机视觉领域的发展前景是多么的不可限量。
让我们一起登上人工智能发展的高速列车。从本文开始,我们将有一系列关于图像处理和目标检测基础知识的教程。本篇是OpenCV入门教程第一部分,完整的系列教程如下:
1. 理解颜色模型与在图像上绘制图形(图像处理基本操作)。
2. 基本的图像处理与过滤。
3. 从特征检测到人脸检测(TBU)
本系列的第一部分将从Opencv的安装,结合代码实战讲解颜色模型与图形绘制讲起。本教程的完整代码已经放在Github上,方便大家使用。
一、OpenCV简介
图像处理是指对图像执行一些操作以达到预期效果的过程。可以类比数据分析工作,在数据分析时我们需要做一些数据预处和特征工程。图像处理也是一样的。我们通过图像处理来处理图片从而可以从中提取处一些更加有用的特征。我们可以通过图像处理减少图像噪声,调整图像亮度、颜色或者对比度等等。想要进一步系统了解图像处理基础知识,参看(https://www.youtube.com/watch?v=QMLbTEQJCaI)。
OpenCV是Open Source Computer Vision的缩写,由英特尔公司于1999年推出。它最初是用C/ C++编写的,所以你可能会看到更多用C语言而不是Python编写的教程。但现在它在Python中也被广泛用于计算机视觉。首先,让我们为使用OpenCV配置环境。安装过程如下,详细安装描述参看(https://pypi.org/project/opencv-python/)。
pip install opencv-python==3.4.2
pip install opencv-contrib-python==3.3.1
安装完成后,可以通过下方两条命令测试其是否正常工作。如果没有任何报错,那么就可以开始使用了!
import cv2
cv2.__version__
我们使用用OpenCV做的第一步就是导入一个图像,如下方所示。
import numpy as np
import matplotlib.pyplot as plt%matplotlib inline# Import the image
img = cv2.imread('burano.jpg')plt.imshow(img)
上图是在意大利最美丽的岛屿之一布拉诺所拍摄的。如果你去过这个地方,你可能会注意到这幅图里有些不同。这确实和我们通常看到的布拉诺的照片有点不同。这是因为OpenCV中颜色模式的默认设置顺序是BGR,不同与Matplotlib。因此,要在RGB模式下查看图像,我们需要将它从BGR转换为RGB,如下所示。
# Convert the image into RGB
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)plt.imshow(img_rgb)
这张图就是真正的布拉诺了,多么美丽!
二、不只是RGB
我们再来谈谈颜色模型。颜色模型是一个使用原色构建全系列颜色的系统。这里先介绍这两种不同的颜色模型:“加色模型”和”减色模型”。加色模型使用光代表计算机屏幕上的颜色,而减色模型使用墨水在纸上打印这些数字图像。前者的原色由红色、绿色和蓝色(RGB)组成,后者有蓝色、品红、黄色和黑色(CMYK)四种原色组成。我们在图像上看到的所有其他颜色都是由这些原色组合或混合而成的。所以当分别用RGB、CMYK表示一张图像时,图像可以有着略微不同地表达。如下图所示。
日常生活中见到最多的就是这两种颜色模型。然而,在彩色模型的世界里不仅仅只有这两种颜色模型。众多的颜色模型中,灰度(grayscale)、HSV和HLS也是你会在计算机视觉任务中经常看到的。
灰度(grayscale)很简单。它通过黑白的强度来表示图像和形态,这也意味着它只有一个通道。要查看灰度图像,我们需要将颜色模型转换为灰色,就像前面对BGR图像所做的操作那样。
# Convert the image into gray scale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)plt.imshow(img_gray, cmap = 'gray')
实际上,RGB图像是由三个通道叠加而成的:R, G, b。所以如果我们把每个通道一个一个的描绘出来,我们就可以理解颜色通道是如何构成的了!
# Plot the three channels of the image
fig, axs = plt.subplots(nrows = 1, ncols = 3,figsize = (20, 20))for i in range(0, 3):ax =axs[i]ax.imshow(img_rgb[:, :, i], cmap = 'gray')plt.show()
观察上面的图片。这三幅图像展示了每个通道是如何组成的。在R通道图中,红色饱和度高的部分看起来是白色的。这是由于红色部分中的值接近255。在灰度模式下,值越高颜色就越白。你还可以使用G或B通道来检查这一点,并比较某些部分之间的差异。
HSV和HLS有一些不同。正如在上图看到的那样,他们有一个三维的表达,更类似于人类的感知方式。HSV代表色调、饱和度和色值。HSL代表色调、饱和度和亮度。HSV的中轴是色值,HSL的中轴是光量。沿着中心轴的角度,有色调和实际的颜色。与中心轴的距离属于饱和度。转换颜色模型的方法如下。
# Transform the image into HSV and HLS models
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
img_hls = cv2.cvtColor(img, cv2.COLOR_BGR2HLS)# Plot the converted images
fig, (ax1, ax2) = plt.subplots(nrows = 1, ncols =2, figsize = (20, 20))
ax1.imshow(img_hsv)
ax2.imshow(img_hls)plt.show()
但是为什么要变换颜色?这些有什么用处?一个很典型的例子--车道检测。观察下图,不同颜色模式下的车道线。在计算机视觉任务中,我们利用掩膜(masking)进行多色模式转换。如果你想了解更多关于图像处理在车道检测任务中的应用,可参看这篇文章。
(https://towardsdatascience.com/finding-lane-lines-simple-pipeline-for-lane-detection-d02b62e7572b)
图像处理是就是对图像数据进行预处理。它可以减少噪音,提取有用的颜色模型,从而简化分类和检测任务。因此,所有上述技术,包括我们稍后将讨论的技术,都是为了帮助模型更容易地实现检测。
三、在图像上绘制图形
让我们在图像上添加一些图形。咱们这次代码示例中使用的图片来自巴黎“爱的墙”。上面用各种国际语言写满了“我爱你”。我们要做的是找到语言中的单词并用矩形标记它们。假如我们要定位韩语版本“我爱你”。首先,复制原始图像并用cv2.rectangle()函数绘制一个矩形,同时给出左上角和右下角的坐标值。如下:
# Copy the image
img_copy = img.copy()# Draw a rectangle
cv2.rectangle(img_copy, pt1 = (800, 470), pt2 =(980, 530),color = (255, 0, 0), thickness = 5)plt.imshow(img_copy)
使用cv2.circle()函数,画一个圆,圈出更多的韩语单词。我们需要指定它的圆心的点和半径的长度。
# Draw a circle
cv2.circle(img_copy, center = (950, 50), radius =50,color = (0, 0, 255), thickness = 5)plt.imshow(img_copy),
我们还可以将文本数据放在图像上。使用cv2.putText()函数,我们可以指定文本的位置、字体样式和大小。
# Add text
cv2.putText(img_copy, text = "the Wall ofLove",org = (250, 250),fontFace = cv2.FONT_HERSHEY_DUPLEX,fontScale = 2,color = (0, 255, 0),thickness = 2,lineType = cv2.LINE_AA)plt.imshow(img_copy)
四、不止是图像
在上边的介绍中,我们选取意大利和法国的两张风景图作为示例。假如,我们想要画张地图把这些地方标出来。那么,首先我们要创建一个窗口并绘制图形。不一样的是这里不是通过指定点绘制图形而是通过点击响应。先试试绘制圆圈。首先创建一个函数,它将用位置和鼠标点击的数据绘制一个圆圈。
# Step 1. Define callback function
def draw_circle(event, x, y, flags, param):ifevent == cv2.EVENT_LBUTTONDOWN:cv2.circle(img, center = (x, y), radius = 5,color = (87, 184, 237), thickness = -1)elifevent == cv2.EVENT_RBUTTONDOWN: cv2.circle(img, center = (x, y), radius = 10, color = (87, 184, 237),thickness = 1)
当按下鼠标点击按钮时,使用cv2.EVENT_LBUTTONDOWN或
cv2.EVENT_RBUTTONDOWN记录位置数据。把鼠标的位置设置为圆心(x, y),并绘制圆圈。
# Step 2. Call the window
img = cv2.imread('map.png')cv2.namedWindow(winname = 'my_drawing')
cv2.setMouseCallback('my_drawing', draw_circle)
设置一个地图作为窗口的背景,并将窗口命名为my_drawing。使用cv2.setMouseCallback()函数,在窗口和我们在步骤1中创建的函数draw_circle之间建立了一个连接。
# Step 3. Execution
while True:cv2.imshow('my_drawing',img)ifcv2.waitKey(10) & 0xFF == 27:breakcv2.destroyAllWindows()
现在我们使用while循环执行窗口。if子句的执行条件是,当我们按下键盘上的ESC时,将窗口设置为关闭。
接下来尝试绘制一个矩形。由于在cv2.rectangle()函数中,矩形需要两个点来表示pt1和pt2,所以我们需要一个额外的步骤来设置第一个点击点为pt1,最后一个点击点为pt2。我们要用cv2.EVENT_MOUSEMOVE和cv2.EVENT_LBUTTONUP来检测鼠标的移动。
我们首先将drawing = False定义为默认值。当按下左键时,绘图变为true,我们将第一个位置设为pt1。如果正在绘图,它将以当前点为pt2,并在移动鼠标时继续绘制矩形。就像数字重叠一样。当左键打开时,绘图变为false,它将鼠标的最后一个位置作为pt2的最后一个点。
# Initialization
drawing = False
ix = -1
iy = -1# create a drawing function
def draw_rectangle(event, x, y, flags, params):globalix, iy, drawingifevent == cv2.EVENT_LBUTTONDOWN:drawing = Trueix,iy = x, yelifevent == cv2.EVENT_MOUSEMOVE:ifdrawing == True:cv2.rectangle(img, pt1=(ix, iy), pt2=(x, y),color = (87, 184,237), thickness = -1) elifevent == cv2.EVENT_LBUTTONUP:drawing = Falsecv2.rectangle(img, pt1=(ix, iy), pt2=(x, y),color = (87, 184, 237),thickness = -1)
在步骤1中将draw_circle函数替换为draw_rectangle。请不要忘记在回调函数cv2.setMouseCallback()中进行更改。因此,整个代码脚本将如下所示。
import cv2
import numpy as np# Step 1. Define callback function
drawing = False
ix = -1
iy = -1def draw_rectangle(event, x, y, flags, params):globalix, iy, drawingifevent == cv2.EVENT_LBUTTONDOWN:drawing = Trueix,iy = x, yelifevent == cv2.EVENT_MOUSEMOVE:ifdrawing == True:cv2.rectangle(img, pt1 = (ix, iy), pt2 = (x, y),color = (87, 184,237), thickness = -1) elifevent == cv2.EVENT_LBUTTONUP:drawing = Falsecv2.rectangle(img, pt1 = (ix, iy), pt2 = (x, y),color = (87, 184, 237),thickness = -1)# Step 2. Call the window
img = cv2.imread('map.png')cv2.namedWindow(winname = 'my_drawing')
cv2.setMouseCallback('my_drawing',draw_rectangle)# Step 3. Execution
while True:cv2.imshow('my_drawing', img)ifcv2.waitKey(10) & 0xFF == 27:breakcv2.destroyAllWindows()
五、总结与展望
本篇文章介绍了Opencv的安装、图像颜色模型的转换与图形绘制。下次,将介绍图像轮廓提出与目标检测等技术。敬请期待!
使用Python+opencv进行图像处理(一) | 视觉入门相关推荐
- python图像处理opencv_使用Python+OpenCV进行图像处理(二)| 视觉入门
[前言]图像预处理对于整个图像处理任务来讲特别重要.如果我们没有进行恰当的预处理,无论我们有多么好的数据也很难得到理想的结果. 本篇是视觉入门系列教程的第二篇.整个视觉入门系列内容如下: 基本的图像处 ...
- 使用Python+OpenCV进行图像处理(二)| 视觉入门
图像预处理对于整个图像处理任务来讲特别重要.如果我们没有进行恰当的预处理,无论我们有多么好的数据也很难得到理想的结果. 本篇是视觉入门系列教程的第二篇.整个视觉入门系列内容如下: 理解颜色模型与在图像 ...
- python opencv 图像切割_使用Python+OpenCV进行图像处理(二)| 视觉入门
译者 | 磐石 编辑 | 安可 [前言]图像预处理对于整个图像处理任务来讲特别重要.如果我们没有进行恰当的预处理,无论我们有多么好的数据也很难得到理想的结果. 本篇是视觉入门系列教程的第二篇.整个视觉 ...
- Python+OpenCV实时图像处理
目录 1.导入库文件 2.设计GUI 3.调用摄像头 4.实时图像处理 4.1.阈值二值化 4.2.边缘检测 4.3.轮廓检测 4.4.高斯滤波 4.5.色彩转换 4.6.调节对比度 5.退出系统 初 ...
- 使用Python+OpenCV进行图像处理(三)| 视觉入门
检测是计算机视觉任务中的主要任务之一,而且应用很广泛.检测技术可以帮助人类检测那些容易被肉眼忽略的错误:也可以"帮助"自动驾驶汽车感知空间信息.无疑自动化的检测技术的广泛应用将为我 ...
- 使用Python+OpenCV进行图像处理之入门教程
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 简介 人脸识别和目标检测这样的术语听起来觉得很酷,但是当涉及到从头 ...
- Python+OpenCV实现图像处理OCR手写数字识别原理
文章目录 一.基本原理 1.载入训练图片: 2.图片分割: 3.灰度处理: 4.数据矩阵化: 5.分配训练集与测试集: 6.将训练测试集进行标定: 7.创建KNN邻近: 8.使用测试集: 二.具体代码 ...
- Python+OpenCV图像处理实验
目录 1.灰度化功能 2.反转功能 3.通道分离功能 4.噪音.滤波功能 5.高斯双边滤波功能 6.均值偏移滤波功能 7.图像二值化功能 8.Canny边缘检测功能 9.直线检测功能 10.圆形检测功 ...
- JavaCV入门指南:调用opencv原生API和JavaCV是如何封装了opencv的图像处理操作?
JavaCV入门指南系列: JavaCV入门指南:序章(看完本章后,不想看原理的小伙伴可直接跳转到<快速上手篇>) JavaCV入门指南:调用FFmpeg原生API和JavaCV是如何封装 ...
最新文章
- 插值查找+代码实现+注意事项
- QC与WIN7、IE8 兼容问题解决方案
- 求解非线性方程f (x)= 0的MATLAB数值法指令介绍(solve、fzero的方法与实例)
- 企业管理器控制台本地无法访问
- 【论文写作】文献资料的作用只是添砖加瓦
- 软件测试的起源;什么是软件测试-定义、类型、方法?
- Borg Maze POJ - 3026 (BFS + 最小生成树)
- tensorflow在文本处理中的使用——Word2Vec预测
- 【语音处理】基于matlab噪声信号功率谱【含Matlab源码 1712期】
- BMZCTF-MISC(一) WriteUp
- 小象学院python数据分析课程怎么样_数据分析和数据挖掘-2016小象学院
- 全网最硬核 JVM TLAB 分析 6. TLAB 相关热门QA汇总
- HTML字母导航栏怎么做,如何用css做导航栏?
- NOIP学习之循环控制:26.质因数分解
- WebSocket(3)---实现一对一聊天功能
- 非零基础自学Golang 第1章 走进Go 1.2 Go语言官方文档 1.3 学好Go 的建议
- 卓越的领导都会讲故事
- debug tools
- 给layim和websocket 菜鸟一个温馨的提示
- 【一分钟解决】python实现多个“字典”之间无分隔符的JSON文件转CSV