嘿!您似乎在 United States,您想使用我们的 English 网站吗?
Switch to English site
Skip to main content

[第一次用Jetson Nano 就上手]OpenCV基础应用

上篇文章教大家使用NVIDIA Jetson Nano来开机,这篇则会带着大家使用常用来做视觉处理的OpenCV,想要一起尝试的朋友可以 (199-9831) 点我取得NVIDIA Jetson Nano Developer Kit

作者 吳怡庭
難度 簡單
材料表
  • NVIDIA Jetson Nano Developer Kit
  • 5V4A变压器
  • 64GB Samsung micro SD卡
  • 外接屏幕(HDMI接头)
  • USB键盘
  • USB鼠标
  • USB Wi-Fi dongle(也可使用有线网络)
  • USB摄影机(本文使用罗技C270 webcam)

一、OpenCV介绍

OpenCV,全名Open Source Computer Vision Library,是一个被广泛使用的计算机视觉函式库,可用于图像处理、运动追踪、图形识别等不同的领域,不仅拥有跨平台的优势(Linux、Windows、Mac等操作系统都可执行),也提供了不同程序语言的接口(例如:C++、Python、Java等),更重要的是,它以BSD条款授权发行,无论是商业或者研究领域,都可以免费使用!

二、OpenCV安装

将Jetson Nano开机(如果您还不会开机操作,请参考我们的开机教学),开启terminal,输入以下指令更新apt套件列表并升级既有套件。

sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get install build-essential
sudo pip3 install opencv-python
sudo apt-get install python3-opencv

由于需要撰写程序代码,请安装nano文本编辑器,也可以使用您习惯的任何编辑器,像是vim、jupyter lab等。

sudo apt-get install nano

在terminal中输入以下指令测试OpenCV是否成功安装

python -c "import cv2; print(cv2.__version__)"

如果显示OpenCV的版本编号就代表安装成功啰!

0128_102918e113aaa1b4db853df97cd299160158c7ad.png

三、拍张照!

在teriminal中输入以下指令查询webcam的编号

ls -ltrh /dev/video*

此范例中查询完得到结果编号为0。

0224_710ec7a00b7e26bc184376d3076423749464d4bd.png

在teriminal中输入以下指令,使用nano文本编辑器建立并撰写Python程序代码,如果后续想编辑程序也可使用相同指令,本文以文件名TakePicture作为范例

nano TakePicture.py

打开文本编辑器后在里面输入以下程序,此范例中使用到OpenCV的VideoCapture()读取影像以及imwrite()储存档案的功能

# 汇入OpenCV库
import cv2
# 设定从哪颗镜头读取影像,在括号中填入先前查询到的webcam编号
webcam = cv2.VideoCapture(0)
# 读取影像
return_value, image = webcam.read()
# 储存名为Picture.png的照片
cv2.imwrite("Picture.png", image)
# 删除webcam,避免影像占用资源
del(webcam)

写完程序请记得按「Ctrl+O」、「Enter」存档,如果要退出编辑请按「Ctrl+X」。

在terminal中输入以下指令,按下「Enter」即可执行程序使用摄影机拍照啦!

python3 TakePicture.py

0326_e059209c90204820e5f61abecd3c67478f6e8802.png

四、读取、编辑、展示影像

此范例使用imread()读取先前使用webcam拍摄的影像,cvtColor()中的cv2.COLOR_BGR2GRAY参数设定将影像从OpenCV默认的BGR格式转换为灰阶,并使用imshow()启动窗口展示影像。

# 汇入库
import cv2
import numpy as np

# 读取影像
img = cv2.imread('Picture.png')
# 将影像转换为灰阶
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
# 存档
cv2.imwrite('img_gray.jpg',img_gray)
# 开启窗口显示影像
cv2.imshow('img_gray',img_gray)
# 不刷新影像
cv2.waitKey(0)
# 释放资源
cv2.destroyAllWindows()

和前一个范例一样,在terminal中使用python3指令执行上方程式。

0413_9de11b420b5bb36aa52225031982e6f73d76e058.jpg

五、提取颜色

OpenCV中可以透过一些运算提取影像中的颜色,如果影像中的颜色较为单一,这项技术可用于简单的对象检测、物体追踪或是去除背景。

# 汇入库
import cv2 
import numpy as np

# 读取图片
img = cv2.imread('Picture.png')

# OpenCV的颜色预设是BGR格式,这边将其转换为HSV格式
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 以HSV格式决定要提取的颜色范围,颜色格式的说明请参考后续内容
lower = np.array([100,43,46])
upper = np.array([124,255,255])
# 将HSV影像的阈值设定为想要提取的颜色
mask = cv2.inRange(hsv, lower, upper)
# 使用bitwise_and()合并掩膜(mask)和原来的影像
img_specific = cv2.bitwise_and(img,img, mask= mask)
# 存档
cv2.imwrite('img_specific.jpg', img_specific)
# 展示原图、掩膜、抽取颜色后的影像
cv2.imshow('img',img)
cv2.imshow('mask',mask)
cv2.imshow(' img_specific ', img_specific)
cv2.waitKey(0)
cv2.destroyAllWindows()

成果如下图,蓝色区域被提取出来啰!

058_18c4b920f0e242c341d4434ecc179b13d9b2d657.jpg

六、RGB、BGR、HSV

这里简单说明一下各个颜色表示的格式。

RGB中文为三原色光模式,是用红(Red)、绿(Green)、蓝(Blue)三原色的色光以不同的比例相加,合成产生各种色彩,而OpenCV中预设的格式为BGR,也就是将顺序调动,如果在程序中需要改变格式,可以使用以下程序代码转换。

cv2.crtColor(影像来源, BGR2RGB)

或是

cv2.crtColor(影像来源, RGB2BGR)

RGB或BGR转换成HSV就比较麻烦一点,各位朋友可以直接参考下表进行此篇文章的提取颜色实作。

06-2_9736160977270894594478e6185cc072406a99d0.png

也可以使用网络上的RGB转HSV色码转换器找到自己需要的颜色,修改上面程序代码中要提取的颜色范围,不过一般的HSV色码为H(0∘~360∘)、S(0%~100%)、V(0%~100%),如要在OpenCV中使用,需要将数字等比例转换成H(0~180)、S(0~255)、V(0~255)的范围。例如蓝色的RGB色码为(0,0,255),经过色码转换器后HSV的色码为(240∘,100%,100%),在OpenCV实作时需输入(120,255,255)。

七、图片叠合及抽色影像

有些摄影家拍摄完会再后制成凸显特定颜色的艺术照片,有了前面实作的成果,我们也可以利用OpenCV的函式来做到类似的效果。

由于直接用使用add()将两张影像叠合会容易导致颜色改变,所以我们需要做一些处理,以下程序也可应用于影像大小一样的图片去背及叠合。

import cv2
import numpy as np
# 读取影像
img_gray = cv2.imread('img_gray.jpg')
img_specific = cv2.imread('img_specific.jpg')

# 将提取颜色的影像转换为灰阶
img_specific_gray = cv2.cvtColor(img_specific,cv2.COLOR_BGR2GRAY)     
# 下方数字50为阈值,可修改阈值范围(0~255)来调整掩膜区域,并转换为二元影像
ret, mask = cv2.threshold(img_specific_gray,50, 255, cv2.THRESH_BINARY)
# 将掩膜反相
mask_inv = cv2.bitwise_not(mask)

# 使用bitwise_and()和掩膜从灰阶图中排除已被提取颜色的区域
img_gray_bg = cv2.bitwise_and(img_gray,img_gray,mask = mask_inv)
# 使用bitwise_and()和掩膜设定提取颜色的区域
img_specific_fg = cv2.bitwise_and(img_specific,img_specific,mask = mask)

# 使用add()将两张图片叠加
img_result = cv2.add(img_gray_bg,img_specific_fg)
# 存档并展示
cv2.imwrite(' img_result.jpg', img_result)
cv2.imshow(' img_result ', img_result)
cv2.waitKey(0)
cv2.destroyAllWindows()

呈现结果就会如下图所示,将提取蓝色的图片和灰阶图结合在一起。

075_b51de14a1a20141283c1430828e261ee59b163c8.jpg

调整参数,lower和upper分别改为[60,43,46]和[88,255,255],迭合图片中的阈值改为30,即会呈现绿色的抽色影像。

085_19143af1fb755866fb4caa5f112bf2818bb3cd93.jpg

八、添加文字

最后教大家在影像中添加文字内容,我们使用putText()函式。

在程序中加入以下内容

cv2.putText(img_result, 'Blue', (100,200), cv2.FONT_HERSHEY_PLAIN, 5, (255, 0, 0), 7, cv2.LINE_AA)

095_bb00947185537bc778796e6c22b61870f7ab0062.jpg

括号中的各项参数分别代表

cv2.putText(影像来源, 文字内容, 坐标, 字型, 字体大小,文字颜色, 线条宽度, 线条种类)

其中坐标是以字符串的左下角为定位,常用的字体可将上方程式码的PLAIN改为SIMPLEX、DUPLEX、COMPLEX、TRIPLEX、COMPLEX_SMALL、SCRIPT_SIMPLEX、SCRIPT_COMPLEX,文字颜色则为前面提过的BGR格式。

本次实作教学就到这边,大家有没有成功做出自己的抽色图片呢?未来我们将会推出更多丰富的内容,有兴趣欢迎关注我们!

看完文章想要使用Jetson Nano实作的朋友可以点此 (194-5741) 取得Jetson Nano开发工具包。

资料来源&相关连结:

OpenCV官网:https://opencv.org/

OpenCV Wiki:https://zh.wikipedia.org/wiki/OpenCV

OpenCV Github:https://github.com/opencv/opencv

OpenCV Tutorials:https://docs.opencv.org/master/d9/df8/tutorial_root.html

OpenCV中文网站:http://www.opencv.org.cn/

图片叠合:https://www.twblogs.net/a/5bb03a202b7177781a0fdf6d

CAVEDU Education is devoted into robotics education and maker movement since 2008, and is intensively active in teaching fundamental knowledge and skills. We had published many books for readers in all ages, topics including Deep Learning, edge computing, App Inventor, IoT and robotics. Please check CAVEDU's website for more information: http://www.cavedu.com, http://www.appinventor.tw
DesignSpark Electrical Logolinkedin