原创:杨其泓

1 OpenCV入门基础

1.1 OpenCV简介

OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起并参与开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理、计算机视觉以及模式识别程序。OpenCV-Python是OpenCV的Python API,集成了Python语言和C++语言的最优特征,致力于支持Python解决计算机视觉问题。

1.2 Python安装OpenCV

在Python中安装OpenCV十分便捷,可以直接使用:pip install opencv-pythonconda insatll opencv-python即可。

注:默认安装最新版,如有特定版本需求,可使用pip install opencv-python==4.1.2

在成功安装OpenCV后,可以在Python编译器中键入如下内容,查看是否安装成功:

import cv2
print(cv2.__version__)

1.3 图片的读取、显示与保存

  1. 图像读取

使用OpenCV读取图片文件,可以使用函数cv2.imread(filepath, flags),例如:

image=cv2.imread('test.jpg')

该函数共接收两个输入,即要读入图片的完整路径和读入图片的方式,常用方式包括以下三种

  • cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道
  • cv2.IMREAD_GRAYSCALE:读入灰度图片
  • cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道

OpenCV读取图片后返回的是一个numpy数组,对于彩色图像,数组为三维数组,其形状(shape)为(图像高,图像宽,3),其中3代表图片的RGB三个通道,由于OpenCV在存储彩色图像时,默认通道顺序为BGR,在进行图像处理时要注意不要使用错误的通道顺序。

  1. 图像显示

使用OpenCV显示图片文件,可以使用函数cv2.imshow(wname, img),例如:

cv2.imshow('Test_image', image)

在多数时候,我们会将上述API搭配cv2.waitKey()cv2.destroyAllWindows()使用,waitKey顾名思义,就是等待键盘键入,而destroyAllWindows就是关闭所有已经显示的窗口,搭配这两个API后即可实现:显示一张图片,并在键盘键入任意值后关闭图片的效果。

下面就是使用OpenCV读入图片并展示的样例代码:

import cv2
image_BGR = cv2.imread('KKB.jpeg', cv2.IMREAD_COLOR)
image_gray = cv2.imread('KKB.jpeg', cv2.IMREAD_GRAYSCALE)
cv2.imshow('BGR', image_BGR)
cv2.imshow('gray', image_gray)
cv2.waitKey()
cv2.destroyAllWindows()

输出效果如下:

  1. 图像保存

使用OpenCV显示图片文件,可以使用函数cv2.imwrite(file, img, num),例如:

cv2.imwrite('testimage.jpeg', image_BGR)
# cv2.imwrite('testimage.jpeg', image_BGR, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
# cv2.imwrite('testimage.jpeg', image_BGR, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])

这个API有三个参数:第一个参数是要保存的文件路径,第二个参数是要保存的图像。第三个参数是可选参数,它针对特定的格式:对于JPEG,其表示的是图像的质量,用0 - 100的整数表示,默认95;对于png ,第三个参数表示的是压缩级别,默认为3。

2 图像处理基础

2.1 像素处理

  1. 访问像素

在OpenCV中,我们可以直接以索引的方式访问图像的像素。例如我们访问刚才读取的图片(200, 200)坐标位置(左上角为坐标系原点)的像素可是使用:

import cv2
image_BGR = cv2.imread('KKB.jpeg', cv2.IMREAD_COLOR)
print(image_BGR[200,200])
>>> [246 218 177]

可见,在(200, 200)坐标位置所对应的三通道像素值分别为B:246,G:218,R:177。

  1. 修改像素

图像像素值的修改也十分简单,下面我们将原始图片中的一部分区域修改为红色(0, 0, 255):

import cv2
image_BGR = cv2.imread('KKB.jpeg', cv2.IMREAD_COLOR)
image_BGR[100:200, 100:200] = [0,0,255]
cv2.imshow('BGR', image_BGR)
cv2.waitKey()
cv2.destroyAllWindows()

所得到的结果为:

2.2 图像属性

  1. 图像形状

图像的形状可以通过image.shape获得,例如:

import cv2
image_BGR = cv2.imread('KKB.jpeg', cv2.IMREAD_COLOR)
print(image_BGR.shape)
>>> (684, 1067, 3)

可以看到,刚才我们打开的那张图片的高是684像素,宽是1067像素,通道数为3。

  1. 像素数目

图像的像素数目可以理解为图像中的像素值总量,也就是行*列*通道,可以通过image.size获得,例如:

import cv2
image_BGR = cv2.imread('KKB.jpeg', cv2.IMREAD_COLOR)
print(image_BGR.size)
>>> 2189484

我们来验证一下,刚才我们打开的那张图片的高是684像素,宽是1067像素,通道数为3,那他的像素数量应为这三者的乘积,即为684∗1067∗3=2189484684*1067*3=2189484684∗1067∗3=2189484,与上述代码中计算所得相同。

  1. 图像类型

图像的类型可以通过image.dtype获得,例如:

import cv2
image_BGR = cv2.imread('KKB.jpeg', cv2.IMREAD_COLOR)
print(image_BGR.dtype)
>>> uint8

由此可见,这张图片的属性是uint8。

3 图像运算

3.1 图像加法

我们知道,以uint8形式存储的图片的取值范围是[0, 255],即0代表纯黑,1代表纯白,0~1之间的值则表示由深到浅的灰色。那么在对图像做加法的时候,就会产生一个问题:像素值为100的图片+像素值为100的图片,可以获得像素值为200的图片,但如果是150+150,两张图片相加之后的像素值超出255的范围怎么办?在这时候,有两种解决方案。

  1. 取模运算

一般来说我们可以直接使用+进行取模运算,即image_c = image_a + image_b。取模运算顾名思义,就是对运算结果取模,此时两个像素值的相加大家可以理解为:

def image_add(pixel_a, pixel_b):if pixel_a + pixel_b <= 255:return pixel_a + pixel_bif pixel_a + pixel_b > 255:return (pixel_a + pixel_b) % 255

也就是在不超出255范围时:100+100=200100+100=200100+100=200,在超出255范围时:150+150=(150+150)%255=45150+150=(150+150)\%255=45150+150=(150+150)%255=45。

  1. 饱和运算

饱和运算就更好理解了,两个像素值相加,如果超出255的限制,则直接取255。使用cv2.add(a, b)即可进行饱和运算。

取模运算和饱和运算的代码及效果图如下:

import cv2
image_a = cv2.imread('dog.jpeg', cv2.IMREAD_GRAYSCALE)
image_b= cv2.imread('cat.jpeg', cv2.IMREAD_GRAYSCALE)image_c = image_a + image_b
image_d = cv2.add(image_a, image_b)cv2.imshow('image_a', image_a)
cv2.imshow('image_b', image_b)
cv2.imshow('image_c', image_c)
cv2.imshow('image_d', image_d)
cv2.waitKey()
cv2.destroyAllWindows()

3.2 图像融合

图像融合其实也是图像加法的一种, 图像融合为两张图像赋予了不同的权重,从而使图像具有混合或透明的感觉。在OpenCV中,可以使用cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])来进行图像融合,此函数会依据下列表达式来进行运算dst=src1∗alpha+src2∗beta+gammadst = src1 * alpha + src2 * beta + gammadst=src1∗alpha+src2∗beta+gamma,也就是对图片1和图片2分别乘一个系数后相加,并添加gamma作为偏置。图像融合的代码及效果图如下:

import cv2
image_a = cv2.imread('dog.jpeg', cv2.IMREAD_GRAYSCALE)
image_b= cv2.imread('cat.jpeg', cv2.IMREAD_GRAYSCALE)image_c = cv2.addWeighted(image_a, 0.5, image_b, 0.5, 0)cv2.imshow('image_a', image_a)
cv2.imshow('image_b', image_b)
cv2.imshow('image_c', image_c)
cv2.waitKey()
cv2.destroyAllWindows()

4 图像几何变换

4.1 图像缩放

图像缩放其实就是改变图像的大小、形状,可以用下列API来实现:

Image = cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

这个API的参数较多,但其实很好理解,下面就是API的参数解释:

  • Image:输出图像
  • src:输入图像
  • dsize:输出图像的尺寸
  • fx:横坐标缩放比例
  • fy:纵坐标缩放比例
  • interpolation:缩放方式

在这些参数中,输入、输出图像都很好理解,输出图像的尺寸dsize是(宽,高),fxfy一般可直接使用0-1的缩放比例,值得注意的一点是,在给定dsize时,就不用另外输入缩放比例了,而想使用缩放比例时,disze应输入None(不可不输入)。缩放方式一般不填,直接使用默认值即可,其他缩放方式如下:

  • INTER_NEAREST 最近邻插值
  • INTER_LINEAR 双线性插值(默认设置)
  • INTER_AREA 使用像素区域关系进行重采样。 它可能是图像抽取的首选方法,因为它会产生无云纹理的结果。 但是当图像缩放时,它类似于INTER_NEAREST方法。
  • INTER_CUBIC 4x4像素邻域的双三次插值
  • INTER_LANCZOS4 8x8像素邻域的Lanczos插值

图像缩放的代码如下:

import cv2
image = cv2.imread('dog.jpeg', cv2.IMREAD_GRAYSCALE)
print(image.shape)
>>> (224, 225)
image = cv2.resize(image,(175,175))
print(image.shape)
>>> (175, 175)

4.2 图像翻转

图像的翻转可以使用cv2.flip(src, flipCode)实现,在这个API中需要输入一个翻转的模式flipCode:

  • flipCode为0代表垂直翻转(沿X轴翻转);
  • flipCode大于0代表水平翻转(沿Y轴翻转);
  • flipCode小于0代表水平垂直翻转(先沿X轴翻转,再沿Y轴翻转,等价于旋转180°)

图片翻转的代码及样例图如下:

import cv2
image= cv2.imread('cat.jpeg', cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image,(300,300))
image_a = cv2.flip(image, -1)
image_b = cv2.flip(image, 0)
image_c = cv2.flip(image, 1)cv2.imshow('image', image)
cv2.imshow('image_a', image_a)
cv2.imshow('image_b', image_b)
cv2.imshow('image_c', image_c)
cv2.waitKey()
cv2.destroyAllWindows()

4.3 图像旋转

图像的旋转比翻转要复杂一些,图像旋转过程中,要先求得旋转矩阵,而后在通过仿射变化函数对图像进行旋转。

cv2.getRotationMatrix2D(center, angle, scale) # 旋转矩阵
cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst # 仿射变化

参数说明

getRotationMatrix2D:

  • center–表示旋转的中心点
  • angle–表示旋转的角度degrees
  • scale–图像缩放因子

warpAffine:

  • src – 输入的图像
  • M – 2 X 3 的变换矩阵.
  • dsize – 输出的图像的size大小
  • dst – 输出的图像
  • flags – 输出图像的插值方法
  • borderMode – 图像边界的处理方式
  • borderValue – 当图像边界处理方式为BORDER_CONSTANT 时的填充值

图片旋转的代码及样例图如下(顺时针转90度):

import cv2
image = cv2.imread('dog.jpeg', cv2.IMREAD_GRAYSCALE)
h, w = image.shapeM = cv2.getRotationMatrix2D((w//2,h//2),-90,1.0)
dst = cv2.warpAffine(image,M,(w,h))cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

5 图像平滑处理

5.1 均值滤波

均值滤波是最简单的滤波器,它取卷积核区域下所有像素的平均值并替换中心元素,均值滤波的代码及样例图如下:

import cv2
image = cv2.imread('dog.jpeg')
img_mean = cv2.blur(image, (5,5)) # 原图,核心大小
cv2.imshow('image', image)
cv2.imshow('img_mean', img_mean)
cv2.waitKey()
cv2.destroyAllWindows()

5.2 中值滤波

中值滤波器是一种非线性滤波器,它的基本原理是:选择待处理像素的一个邻域中各像素值的中值来代替待处理的像素。它能使某像素的灰度值与周围领域内的像素比较接近,从而消除一些孤立的噪声点,所以中值滤波器能够很好的消除椒盐噪声。中值滤波的代码及样例图如下:

import cv2
image = cv2.imread('dog.jpeg')
img_median = cv2.medianBlur(image, 5) # 原图,核心大小
cv2.imshow('image', image)
cv2.imshow('img_median', img_median)
cv2.waitKey()
cv2.destroyAllWindows()

5.3 高斯滤波

高斯滤波也是一种常见的滤波器,与中值滤波不同的是,它是使用高斯核心来计算的:
h(x,y)=e−(x2+y2)2σ2h(x,y)=e^{\frac{-(x^2+y^2)}{2\sigma^2}} h(x,y)=e2σ2−(x2+y2)​
其中(x,y)(x,y)(x,y)是图像中的点的坐标, σ\sigmaσ为标准差。x和y都是代表以核中心点为坐标原点的坐标值,对于而言 σ\sigmaσ,当 σ\sigmaσ比较小的时候,生成的高斯模板中心的系数比较大,而周围的系数比较小,这样对图像的平滑效果不明显。当比较大时 σ\sigmaσ,生成的模板的各个系数相差就不是很大,比较类似于均值模板,对图像的平滑效果比较明显。高斯滤波的代码及样例图如下:

import cv2
image = cv2.imread('dog.jpeg')
img_Guassian = cv2.GaussianBlur(image,(5,5),0) # 原图,核心大小,sigma
cv2.imshow('image', image)
cv2.imshow('img_Guassian', img_Guassian)
cv2.waitKey()
cv2.destroyAllWindows()

5.4 双边滤波

双边滤波是一种非线性滤波方法,是结合了图像的邻近度和像素值相似度的一种折中,在滤除噪声的同时可以保留原图的边缘信息。整个双边滤波是由两个函数构成:一个函数是由空间距离决定的滤波器系数,另外一个诗由像素差值决定的滤波器系数,双边滤波具体计算过程在这里就不赘述了。双边滤波的代码及样例图如下:

import cv2
image = cv2.imread('dog.jpeg')
img_bilater = cv2.bilateralFilter(image,9,75,75)
cv2.imshow('image', image)
cv2.imshow('img_bilater', img_bilater)
cv2.waitKey()
cv2.destroyAllWindows()

OpenCV常用操作相关推荐

  1. opencv 常用操作 c++

    图像水平垂直方向拼接: cv::vconcat(B,C,A); // 等同于A=[B ;C] cv::hconcat(B,C,A); // 等同于A=[B C] 初始化Mat: cv::Mat edg ...

  2. opencv 图像操作,常用 OpenCV 内置函数

    OpenCV 如何对图像的像素进行操作 对图像的像素进行操作,我们可以实现空间增强,反色,大部分图像特效系列都是基于像素操作等目的.先来看一下内存空间中图像矩阵,也就是Mat的矩阵数值部分是怎么存储的 ...

  3. OpenCV形态学操作

    OpenCV形态学操作 本文转载自:http://blog.csdn.net/byxdaz/article/details/5775717 一.图像腐蚀 膨胀 细化的基本原理   1.图像细化的基本原 ...

  4. Eigen::常用操作[转]

    Opencv::Mat 与 Eigen互转 Opencv::Mat转Eigen #include <Eigen/Dense> #include <iostream> #incl ...

  5. 【无标题】c++ MFC图像处理CImage类常用操作代码

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9598974.html 我看了一下发现关于c++下的CImage图像处理类 的图像处理相关的介绍 ...

  6. Opencv的使用小教程2——Opencv常用图像处理函数汇总

    Opencv的使用小教程2--Opencv常用图像处理函数汇总 1.blur 2.GaussianBlur 3.medianBlur 4.bilateralFilter 5.腐蚀和膨胀 6.morph ...

  7. TensorFlow常用操作:代码示例

    1,定义矩阵代码示例: import tensorflow as tftf.zeros([3,4]) #定义3行4列元素均为0的矩阵tensor=tf.constant([1,2,3,4])#定义一维 ...

  8. Ubuntu 常用操作

    Ubuntu常用操作 外观操作 修改应用icon图标 终端美化 内存管理 内存查询 分区管理 日志清理 操作执行 自动执行多条命令 外观操作 修改应用icon图标 在/usr/share/applic ...

  9. IOS沙盒Files目录说明和常用操作

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...

最新文章

  1. ASP.NET页面事件:顺序与回传详解
  2. C++中public protected private的区别
  3. 判断CPU大小端模式
  4. 1192 约瑟夫问题(1)
  5. 八皇后问题 (信息学奥赛一本通-T1213)
  6. 地图的文字注记的制作和优化
  7. 在Hisi3531环境中为wm8978芯片添加音量调节功能及测试
  8. 【太经典】如果有人问你数据库的原理,叫他看这篇文章
  9. 深入解析棋牌湖南放炮罚,跑胡子手游源码(java版)
  10. Could not enlist in transaction on entering meta-aware object!”
  11. 转:苹果CEO库克:伟大的想法来自不断拒绝接受现状
  12. 杭电ACM 2014:青年歌手大奖赛_评委会打分
  13. 全面解析ThreadLocal
  14. 投稿Springer旗下Natural Hazard的时间记载
  15. 2022渗透测试-面试题目大全
  16. MMSC BAPI/自动扩充库位
  17. GB28181/RTSP/Onvif/HikSDK/Ehome协议视频共享平台EasyCVR人脸识别系统助力打造智慧安检系统
  18. c#调用VLC播放视频,rtsp流
  19. HTML+CSS大作业:基于HMTL校园学校网页设计题材【我的学校网站】
  20. microblaze c语言,MicroBlaze

热门文章

  1. 外骨骼之人体行走的研究
  2. 公众号1200篇文章分类和索引
  3. 2018诺贝尔经济学奖得主,一名62岁的Python教徒
  4. A*算法求解N数码问题(AI实验一)
  5. unity编辑器上不穿模,真机Android上会穿模问题定位和解决
  6. 【SHARE分享】---GitChat程序猿的必备补给站
  7. 利用定时器 1和定时器0控制led1和led2分别 2hz和0.5hz闪烁
  8. 液体采样泵WKA1000升级品WKY1000
  9. 《EMBEDDING AND BEAMFORMING: ALL-NEURAL CAUSAL BEAMFORMER FORMULTICHANNEL SPEECH ENHANCEMENT》论文阅读
  10. linux配置网络(超级详细)