您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
首页
博文
课程
大赛
工具
更多
用户中心
开发者社区
>
博文
>
Opencv系列之一:简介与基本使用
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
Opencv系列之一:简介与基本使用
自猿其说Tech
2022-07-12
IP归属:未知
110840浏览
计算机编程
### 1 Opencv简介 Opencv是计算机视觉中经典的专用库,其支持多语言,跨平台,功能强大。Opencv-Python为Opencv提供了Python接口,使得使用者在Python中能够调用C/C++,在保证易读性和运行效率的前提下,实现所需的功能。 Opencv是由Gray Bradsky于1999年在英特尔创立,第一版于2000年问世。Vadim Pisarevsky加入Gary Bradsky,一起管理因特尔的俄罗斯软件Opencv团队。 2005年,Opencv用于Stanley,该车赢得了2005年DARPA挑战赛的冠军。后来,在Willow Garage的支持下,它的积极发展得以继续,由Gary Bradsky和Vadim Pisarevsky领导了该项目。Opencv现在支持与计算机视觉和机器学习有关的多种算法,并且正在日益扩展。 Opencv支持多种编程语言,例如C++, Python, Java等,并且可以再Windows , Linux , OS X , Android和IOS等不同平台上使用。基于CUDA和OpenCL的高速GPU操作的接口也在积极开发中。 Opencv-Python是用于Opencv的Python API,结合了Opencv C++ API和Python语言的最佳特性。 #### 1.1 Opencv-Python Opencv-Python是旨在解决计算机视觉问题的专用库 Python是由Guidovan Rossum发起的通用编程语言,很快就非常流行,主要是因为他的简单性和代码可读性。它使得程序员可以用较少的代码行表达想法,而不会降低可读性。 与C/C++之类的语言,Python速度较慢。也就是说,可以使用C/C++轻松扩展Python,这使得我们能够用C/C++编写计算机密集型代码并创建可用作Python模块的Python包装器。它给我们带来了两个好处: 首先,代码与原始C/C++代码一样快(因为它是在后台运行的实际C++代码), 其次,在Python中比C/C++编写代码更容易。Opencv-Python是原始Opencv C++实现的Python包装器。 Opencv-Python利用了Numpy,这是一个高度优化的库,用于使用MATLAB样式的语言进行数值运算。所有Opencv数组结构都与Numpy数组相互转换。这也使与使用Numpy的其他库(例如Scipy和Matplotlib)的集成变得更加容易。 1.2 应用领域 - 人机互动 - 物体识别 - 图像分割 - 人脸识别 - 动作识别 - 运动跟踪 - 机器人 - 运动分析 - 机器视觉 - 结构分析 - 汽车安全驾驶 如上所述,opencv的功能十分强大,在各个领域大放异彩,由浅入深,本次我们先介绍图像编辑,简单的字母数字识别的相关部分,日后会继续开始人脸识别,图像分割,图像定位等等功能; ### 2 opencv-python安装与使用 首先我们需要安装一下环境 1. python3:安装python3:python教程有详细的说明,网址安装python 2. numpy:安装numpy:pip install numpy 3. opencv-python:安装opencv-python: pip install opencv-python 安装完opencv-python后命令行打开python交互式环境:import cv2 成功,便说明成功安装了opencv-python #### 2.1 imread() imread函数读取数字图像,先看一下官网对于该函数的定义 ```python cv2.imread(path_of_image, intflag) ``` 函数参数一: 需要读入图像的完整的路径 函数参数二: 标志以什么形式读入图像,可以选择一下方式: - cv2.IMREAD_COLOR: 加载彩色图像。任何图像的透明度都将被忽略。它是默认标志 - cv2.IMREAD_GRAYSCALE:以灰度模式加载图像 - cv2.IMREAD_UNCHANGED:保留读取图片原有的颜色通道 - 1 :等同于cv2.IMREAD_COLOR - 0 :等同于cv2.IMREAD_GRAYSCALE - -1 :等同于cv2.IMREAD_UNCHANGED ```python color_img = cv2.imread("image_file/1.jpeg") print(color_img.shape) gray_img=cv2.imread("image_file/1.jpeg", cv2.IMREAD_GRAYSCALE) print(gray_img.shape) #把单通道图像保存后,再读取,仍然是3通道,相当于将单通道复制到3个通道保存 cv2.imwrite("image_file/gray_1.jpeg",gray_img) ``` ![](//img1.jcloudcs.com/developer.jdcloud.com/fb5f5652-cccf-43fe-9c6d-18ae1f825f6020220712154802.png) ![](//img1.jcloudcs.com/developer.jdcloud.com/f67e45b2-6cb4-4eb7-a3cc-718a2c01872920220712154807.png) #### 2.2 threshold() 这个函数作用是将图片二值化,图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。二值化是图像分割的一种最简单的方法。二值化可以把灰度图像转换成二值图像。把大于某个临界灰度值的像素灰度设为灰度极大值,把小于这个值的像素灰度设为灰度极小值,从而实现二值化。 画图举例来说 ![](//img1.jcloudcs.com/developer.jdcloud.com/4e40dd0a-6794-4969-ad5a-9c484828d1cd20220712154825.png) cv.threshold()用来实现阈值分割,函数有4个参数: - 参数1:要处理的原图,一般是灰度图,这也是上一步中处理的 - 参数2:设定的阈值 - 参数3:最大阈值,一般为255 - 参数4:阈值的方式,主要有5种,分别为:THRESH_BINARY,THRESH_BINARY_INV,THRESH_TRUNC,THRESH_TOZERO 和 THRESH_TOZERO_INV 实例如下: ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY) ret, th2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV) ret, th3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC) ret, th4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO) ret, th5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV) titles = ['Original', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV'] images = [img, th1, th2, th3, th4, th5] 使用Matplotlib显示 for i in range(6): plt.subplot(2, 3, i + 1) plt.imshow(images[i], 'gray') plt.title(titles[i], fontsize=8) plt.xticks([]), plt.yticks([]) # 隐藏坐标轴 plt.show() 实际输出: ![](//img1.jcloudcs.com/developer.jdcloud.com/9f4636e9-9901-489a-abcb-75551a4cde5920220712154909.png) 对应的官方中说明 ![](//img1.jcloudcs.com/developer.jdcloud.com/7caa7be2-3a01-44a6-b491-28151799007c20220712154920.png) #### 2.3 morphologyEx() 形态学操作是根据图像形状进行的简单操作。一般情况下对二值化图像进行的操作。需要输入两个参数,一个是原始图像,第二个被称为结构化元素或核,它是用来决定操作的性质的。 两个基本的形态学操作是腐蚀和膨胀。他们的变体构成了开运算,闭运算,具体概念如下: ###### 1)腐蚀: 就像土壤侵蚀一样,这个操作会把前景物体的边界腐蚀掉(但是前景仍然是白色)。这是怎么做到的呢?卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是1,那么中心元素就保持原来的像素值,否则就变为零。 这会产生什么影响呢?根据卷积核的大小靠近前景的所有像素都会被腐蚀掉(变为0),所以前景物体会变小,整幅图像的白色区域会减少。这对于去除白噪声很有用,也可以用来断开两个连在一块的物体等。 ###### 2)膨胀: 与腐蚀相反,与卷积核对应的原图像的像素值中只要有一个是1,中心元素的像素值就是1。 所以这个操作会增加图像中的白色区域(前景)。一般在去噪声时先用腐蚀再用膨胀。因为腐蚀在去掉白噪声的同时,也会使前景对象变小。所以我们再对他进行膨胀。这时噪声已经被去除了,不会再回来了,但是前景还在并会增加。膨胀也可以用来连接两个分开的物体。 ###### 3)开运算: 先腐蚀,后膨胀。去除图像中小的亮点(CV_MOP_OPEN); ###### 4)闭运算 先膨胀,后腐蚀。去除图像中小的暗点(CV_MOP_CLOSE); ``` kernel = cv.getStructuringElement(cv.MORPH_RECT, (1, 8)) opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) cv.imshow("MORPH_OPEN_1", opening) cv2.waitKey(0) ``` ![](//img1.jcloudcs.com/developer.jdcloud.com/48ea0e0b-637f-42d4-a767-29f4de89956b20220712155027.png) ``` kernel = cv.getStructuringElement(cv.MORPH_RECT, (1, 8)) closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) cv.imshow("MORPH_OPEN_1", closing) cv2.waitKey(0) ``` ![](//img1.jcloudcs.com/developer.jdcloud.com/a11f3d26-2eeb-44e1-b25e-1cee34158fb020220712155048.png) ### 3 应用案例 以上是opencv的简单使用,现在举一个实际应用的案例:识别验证码,其实按照上面3个步骤就可以将图片一步步处理,置灰,二值化,开运算,最后就可以识别了。那么首先原图如下: ![](//img1.jcloudcs.com/developer.jdcloud.com/c888d71a-bbc5-4443-a2fd-345e2c33c3c020220712155257.png) 1)首次处理效果,将图片灰度化,二值化,为提取轮廓做准备,二值化后,图片非黑即白两种,更有利于开闭运算处理 ```python src = cv2.imread('image_file/before.png') gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU) cv.imshow("Binarization", binary) cv2.waitKey(0) ``` ![](//img1.jcloudcs.com/developer.jdcloud.com/5a32adae-108d-4410-a622-993099f94f8520220712155416.png) 2)基础上面二值化图片,对结果图进行开运算处理,去除噪音部分 ```python kernel = cv.getStructuringElement(cv.MORPH_RECT, (8, 1)) open_out = cv.morphologyEx(binl, cv.MORPH_OPEN, kernel) cv.imshow("MORPH_OPEN_2", open_out) cv2.waitKey(0) ``` ![](//img1.jcloudcs.com/developer.jdcloud.com/b54a6068-14e6-4471-9688-e6e43606cbdb20220712155449.png) 3)最后一次处理,将背景置为白色,并且识别图片识别码 ```python cv.bitwise_not(open_out, open_out) cv.imshow("Transform", open_out) textImage = Image.fromarray(open_out) text = pytesseract.image_to_string(textImage) cv2.waitKey(0) ``` ![](//img1.jcloudcs.com/developer.jdcloud.com/828ace53-a5c4-4e3e-b642-24154210a60a20220712155516.png) 4)最后打印出验证码 ![](//img1.jcloudcs.com/developer.jdcloud.com/db41496c-4f5f-4874-9c22-6ba6f85a891120220712155529.png) ### 4 总结 相信认真一起看完上述知识点,opencv-python已经对于图像的基本操作可以熟练掌握了,接下来会对数字图像的一些其他概念进行介绍,敬请期待~ ------------ ###### 自猿其说Tech-JDL京东物流技术与数据智能 ###### 作者:张伟男
原创文章,需联系作者,授权转载
上一篇:通过MockMVC实现REST接口单测化的测试
下一篇:项目开展CICD的实践探路
相关文章
Taro小程序跨端开发入门实战
Flutter For Web实践
配运基础数据缓存瘦身实践
自猿其说Tech
文章数
426
阅读量
2149940
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
自猿其说Tech
文章数
426
阅读量
2149940
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号