OpenCV学习笔记(三)——图像像素(图像的最大(小)值、均值、标准差、比较运算、逻辑运算、图像二值化)
目录
- 1 图像像素统计
- 1.1 图像像素的最大值和最小值
- 1.2 计算图像的均值和标准差
- 2 两图像间的像素操作
- 2.1 比较运算
- 2.2 逻辑运算
- 3 图像二值化
1 图像像素统计
数字图像可以用大小一定的矩阵来表示,矩阵中每个元素的大小表示图像中每个像素的明暗程度。查找矩阵中的最大值就是寻找图像中灰度值最大的像素,计算矩阵的平均值就是计算图像的平均灰度(图像的整体亮暗程度可以用平均灰度来表示)。因此,统计矩阵数据的特征值具有一定的意义。
1.1 图像像素的最大值和最小值
OpenCV 4中提供了寻找图像像素最大值、最小值的函数 cv.minMaxLoc()
#cv.minMaxLoc()函数原型
minVal, maxVal, minLoc, maxLoc = cv.minMaxLoc(src[, mask])
其中各返回值和参数的含义分别为:
minVal:图像中的最小值
maxVal:图像中的最大值
minLoc:图像最小值在矩阵中的坐标
maxLoc:图像最大值在矩阵中的最表
src:需要寻找最大值和最小值的图像或者矩阵
mask:图像掩模(可选参数)
需要注意的是如果图像中存在多个最大值或最小值,则返回的最值坐标为按行扫描从左到右第1次检查到的最值位置。
示例代码
#cv.minMaxLoc()函数原型
# -*- coding:utf-8 -*-
import cv2 as cv
import numpy as npif __name__ == '__main__':# 新建矩阵arrayarray = np.array([1, 2, 3, 4, 5, 10, 6, 7, 8, 9, 10, 0])# 将array调整为3*4的单通道图像img1 = array.reshape((3, 4))minval_1, maxval_1, minloc_1, maxloc_1 = cv.minMaxLoc(img1)print('图像img1中最小值为:{}, 其位置为:{}' .format(minval_1, minloc_1))print('图像img1中最大值为:{}, 其位置为:{}' .format(maxval_1, maxloc_1))# 先将array调整为为3*2*2的多通道图像img2 = array.reshape((3, 2, 2))# 再利用-1的方法调整尺寸img2_re = img2.reshape((1, -1))minval_2, maxval_2, minloc_2, maxloc_2 = cv.minMaxLoc(img2_re)print('图像img2中最小值为:{}, 其位置为:{}'.format(minval_2, minloc_2))print('图像img2中最大值为:{}, 其位置为:{}'.format(maxval_2, maxloc_2))
运行结果如下图所示。
1.2 计算图像的均值和标准差
图像的均值可以用于表示图像整体的亮暗程度,图像的均值越大,图像整体越亮。
图像的标准差表示图像中明暗变化程度,标准差越大,表示图像中明暗变化越明显。
OpenCV4中提供了计算图像均值和标准差的函数。
(1)cv.mean()函数可计算图像的均值。
#cv.mean()函数原型
retal = cv.mean(src[,mask])
其中各返回值和参数的含义分别为:
retal:为一个长度为4的元组,四个位置分别代表相应通道的均值,若通道不存在,则对应值为0.0
src:需要计算均值的图像或者矩阵
mask:图像掩模(可选参数)
该函数计算的原理如下式所示:
N=∑I,mask(I)≠01Mc=(∑I,mask(I)≠0src(I)c)/N\begin{aligned} N &=\sum_{I, \operatorname{mask}(I) \neq 0} 1 \\ M_{c} &=\left(\sum_{I, \operatorname{mask}(I) \neq 0} \operatorname{src}(I)_{c}\right) / N \end{aligned} NMc=I,mask(I)=0∑1=⎝⎛I,mask(I)=0∑src(I)c⎠⎞/N
其中,McM_cMc表示第c个通道的均值,III表示输入图像;src(I)csrc(I)_csrc(I)c表示第c个通道中像素的灰度值。
(2)cv.meanStdDev()函数可同时计算图像的均值和标准差。
#cv.meanStdDev()函数原型
mean, stddev = cv.meanStdDev(src[, mean[, stddev[, mask]]])
其中各返回值参数的含义分别为:
mean:图像每个通道的均值
stddev:图像每个通道的标准差
src:需要计算均值的图像或者矩阵
mask:图像掩模(可选参数)
该函数计算的原理如下式所示:
N=∑I,mask (I)≠01Mc=(∑I,mask (I)≠0src(I)c)/Nstddevc=∑I,mask(I)≠0(src(I)c−Mc)2/N\begin{aligned} N &=\sum_{I, \text { mask }(I) \neq 0} 1 \\ M_{c} &=\left(\sum_{I, \text { mask }(I) \neq 0} \operatorname{src}(I)_{c}\right) / N \\ \operatorname{stddev}_{c} &=\sqrt{\sum_{I, \operatorname{mask}(I) \neq 0}\left(\operatorname{src}(I)_{c}-M_{c}\right)^{2} / N} \end{aligned} NMcstddevc=I, mask (I)=0∑1=⎝⎛I, mask (I)=0∑src(I)c⎠⎞/N=I,mask(I)=0∑(src(I)c−Mc)2/N
示例代码
# -*- coding:utf-8 -*-
import cv2 as cv
import numpy as npif __name__ == '__main__':# 新建矩阵arrayarray = np.array([1, 2, 3, 4, 5, 10, 6, 7, 8, 9, 10, 0])# 将array调整为3*4的单通道图像img1img1 = array.reshape((3, 4))# 将array调整为3*2*2的多通道图像img2img2 = array.reshape((3, 2, 2))# 分别计算图像img1和图像img2的平均值和标准差mean_img1 = cv.mean(img1)mean_img2 = cv.mean(img2)mean_std_dev_img1 = cv.meanStdDev(img1)mean_std_dev_img2 = cv.meanStdDev(img2)# 输出cv.mean()函数计算结果print('cv.mean()函数计算结果如下:')print('图像img1的均值为:{}'.format(mean_img1))print('图像img2的均值为:{}\n第一个通道的均值为:{}\n第二个通道的均值为:{}'.format(mean_img2, mean_img2[0], mean_img2[1]))print('*' * 30)# 输出cv.meanStdDev()函数计算结果print('cv.meanStdDev()函数计算结果如下:')print('图像img1的均值为:{}\n标准差为:{}'.format(mean_img1[0], float(mean_std_dev_img1[1])))print('图像img2的均值为:{}\n第一个通道的均值为:{}\n第二个通道的均值为:{}\n''标准差为:{}\n第一个通道的标准差为:{}\n第二个通道的标准差为:{}\n'.format(mean_img2, mean_img2[0], mean_img2[1],mean_std_dev_img2[1], float(mean_std_dev_img2[1][0]), float(mean_std_dev_img2[1][0])))
运行结果如下图所示。
2 两图像间的像素操作
2.1 比较运算
OpenCV4中提供了求取两幅图中较大或较小灰度值的cv.max()、cv.min()函数,这两个函数依此比较两幅图像中灰度值的大小,返回值为两幅图像中较大(较小)的灰度值。
#cv.max()和cv.min()函数原型
dst = cv.max(src1,src2,[, dst])
dst = cv.min(src1,src2,[, dst])
其中各返回值和参数的含义分别为:
dst:保留对应位置上较大(较小)灰度值后的图像,尺寸、通道数和数据类型与输入参数一致
src1:第一幅图像,可以是任意通道数的矩阵
src2:第二幅图像,图像的尺寸、通道数以及数据类型需要与第一幅图像一致
2.2 逻辑运算
OpenCV4提供了针对两幅图像像素之间的“与”、“或”、“异或”及“非”运算的函数。具体运算规则如下图所示。
像素逻辑运算函数的原型
//对像素求"与"运算
dst = cv.bitwise_and(src1,src2,[, dst[, mask]])
//对像素求"或"运算
dst = cv.bitwise_or(src1,src2,[, dst[, mask]])
//对像素求"异或"运算
dst = cv.bitwise_xor(src1,src2,[, dst[, mask]])
//对像素求"非"运算
dst = cv.bitwise_not(src1,src2,[, dst[, mask]])
其中各返回值和参数的含义分别为:
dst:逻辑运算之后的结果,尺寸、通道数和数据类型与输入参数一致
src1:第一幅图像,可以是任意通道数的矩阵
src2:第二幅图像,图像的尺寸、通道数以及数据类型需要与第一幅图像一致
mask:掩模矩阵,用于设置图像或矩阵中逻辑运算的范围
示例代码
# -*- coding:utf-8 -*-
import cv2 as cv
import numpy as npif __name__ == '__main__':# 创建两个黑白图像img1 = np.zeros((200, 200), dtype='uint8')img2 = np.zeros((200, 200), dtype='uint8')img1[50:150, 50:150] = 255img2[100:200, 100:200] = 255# 进行逻辑运算Not = cv.bitwise_not(img1)And = cv.bitwise_and(img1, img2)Or = cv.bitwise_or(img1, img2)Xor = cv.bitwise_xor(img1, img2)# 展示结果cv.imshow('img1', img1)cv.imshow('img2', img2)cv.imshow('Not', Not)cv.imshow('And', And)cv.imshow('Or', Or)cv.imshow('Xor', Xor)cv.waitKey(0)cv.destroyAllWindows()
运行结果如下图所示。
3 图像二值化
在前面的程序中,我们生成了只有黑色和白色的图像,我们将这种只有两种灰度值的图像称为二值图像。二值图像的色彩种类少,可以进行高度压缩,以节省存储空间。将非二值图像经过计算变成二至图像的过程称为图像的二值化或阈值化。OpenCV4提供了cv.threshold()和cv.adapticeThredhold()函数用于实现图像二值化
(1)cv.threshold()
#cv.threshold()函数原型
retval , dst = cv.threshold(src,thresh,maxval,type,[, dst])
其中各返回值和参数的含义分别为:
dst:二值化后的图像,尺寸、通道数和数据类型与输入图像src一致
src:需要二值化的图像,图像的数据类型只能是uint8或float32,这与图像通道数目的要求和选择的二值化方法相关
thresh:二值化的阈值
maxval:二值化过程中的最大值,此参数只有选择 THRESH_BINARY 和 THRESH_BINARY_INV这两种二值化方法时才发挥作用,但是在使用其他方法时也需要输入参数
type:图像二值化的方法
具体图像二值化方法标志如下标所示
标志 | 简记 | 作用 |
---|---|---|
THRESH_BINARY | 0 | 若灰度值大于阈值,取最大值,对于其他值,取0 |
THRESH_BINARY_INV | 1 | 若灰度值大于阈值,取0 ,对于其他值,取最大值 |
THRESH_TRUNC | 2 | 若灰度值大于阈值,取阈值,对于其他值,不变 |
THRESH_TOZERO | 3 | 若灰度值大于阈值, 不变,对于其他值,取0 |
THRESH_TOZERO_INV | 4 | 若灰度值大于阈值,取0,对于其他值,不变 |
THRESH_OTSU | 8 | 使用大津法自动寻求全局阈值 |
THRESH_TRIANGLE | 16 | 使用三角形法自动寻求全局阈值 |
不同二值化方法示例如下图所示
(2)cv.adaptiveThreshold()
#cv.adaptiveThreshold()函数原型dst = cv.adaptiveThreshold(src,maxValue,adaptiveMethod,thresholdType,blockSize,C,[, dst])
其中各返回值和参数的含义分别为:
dst:二值化后的图像,尺寸、通道数和数据类型与输入图像src一致
src:需要二值化的图像,图像的数据类型只能是uint8单通道类型
adaptiveMethod:自适应确定阈值的方法,有均值法(cv.ADAPTIVE_THRESH_MEAN_C)和高斯法(cv.ADAPTIVE_THRESH_GAUSSIAN_C)两种
thresholdType:选择图像二值化的方法,只能是cv.THREASH_BINARY或cv.THREASH_BINARY_INV
blockSize:自适应确定阈值的像素领域大小,一般取值为3、5、7
C:从平均值或加权平均值中减去的常数,可以为正数或负数
示例代码
# -*- coding:utf-8 -*-
import cv2 as cv
import numpy as npif __name__ == '__main__':# 读取图像并判断是否读取成功img = cv.imread('./images/lena.jpg')if img is None:print('Failed to read lena.jpg.')sys.exit()gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# 彩色图像二值化_, img_B = cv.threshold(img, 125, 255, cv.THRESH_BINARY)_, img_B_V = cv.threshold(img, 125, 255, cv.THRESH_BINARY_INV)cv.imshow('img_B', img_B)cv.imshow('img_B_V', img_B_V)# 灰度图像二值化_, gray_B = cv.threshold(gray, 125, 255, cv.THRESH_BINARY)_, gray_B_V = cv.threshold(gray, 125, 255, cv.THRESH_BINARY_INV)cv.imshow('gray_B', gray_B)cv.imshow('gray_B_V', gray_B_V)# 灰度图像TOZERO变换_, gray_T = cv.threshold(gray, 125, 255, cv.THRESH_TOZERO)_, gray_T_V = cv.threshold(gray, 125, 255, cv.THRESH_TOZERO_INV)cv.imshow('gray_T', gray_T)cv.imshow('gray_T_V', gray_T_V)# 灰度图像TRUNC变换_, gray_TRUNC = cv.threshold(gray, 125, 255, cv.THRESH_TRUNC)cv.imshow('gray_TRUNC', gray_TRUNC)# 灰度图像大律法和三角形法二值化img1 = cv.imread('./images/threshold.png', cv.IMREAD_GRAYSCALE)_, img1_O = cv.threshold(img1, 100, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)_, img1_T = cv.threshold(img1, 125, 255, cv.THRESH_BINARY | cv.THRESH_TRIANGLE)cv.imshow('img1', img1)cv.imshow('img1_O', img1_O)cv.imshow('img1_T', img1_T)# 灰度图像自适应二值化adaptive_mean = cv.adaptiveThreshold(img1, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 13, 0)adaptive_gauss = cv.adaptiveThreshold(img1, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 13, 0)cv.imshow('adaptive_mean', adaptive_mean)cv.imshow('adaptive_gauss', adaptive_gauss)cv.waitKey(0)cv.destroyAllWindows()
部分运行结果如下图所示。
下一篇将会介绍OpenCV中图像的连接与变换等操作。
OpenCV学习笔记(三)——图像像素(图像的最大(小)值、均值、标准差、比较运算、逻辑运算、图像二值化)相关推荐
- opencv学习笔记3:像素处理
学习笔记,看的某宝的一个视频学习的 读取像素 返回值=图(位置参数) 灰度图读取像素 灰度度只有两维 d=img[78,155] print(d) 彩色图读取像素 彩色图 有三个通道. 注意openc ...
- OpenCV学习笔记02--图像像素处理--二值图像、灰度图像、彩色图像像素的处理、numpy.array中的对应的函数
目录 (一)灰度图像像素处理 (二)彩色图像像素处理 (三)numpy.array库在图像处理中的应用 (四)查看图像的属性信息 接着笔记01继续总结,当我们读取一幅图像的时候,一般为二值图像.灰度图 ...
- Opencv学习笔记(三) -- 图像压缩与保存
1.图像压缩 1.1常用图像格式 bmp Windows位图格式.该格式为不压缩格式,缺点是图像文件较大. jpg JPEG是为静态图像所建立的第一个国际数字图像压缩标准,也是至今一直在使用的.应用最 ...
- opencv学习笔记 边缘滤波保留(EPF) 高斯双边 均值迁移
双边滤波函数bilateralFilter():定义:bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None ...
- OpenCV学习笔记三-Mat数据结构
主要记录Mat数据结构的一些操作 P3 Mat 数据结构的一些操作 #include<opencv2/opencv.hpp> #include<iostream>using n ...
- brisk matlab,opencv学习笔记三十七:BRISK特征点检测与匹配
简介 BRISK算法是2011年ICCV上<BRISK:Binary Robust Invariant Scalable Keypoints>文章中,提出来的一种特征提取算法,也是一种二进 ...
- opencv学习笔记三十六:AKAZE特征点检测与匹配
KAZE是日语音译过来的 , KAZE与SIFT.SURF最大的区别在于构造尺度空间,KAZE是利用非线性方式构造,得到的关键点也就更准确(尺度不变性 ): Hessian矩阵特征点检测 ,方向指定, ...
- 《opencv学习笔记》-- 亚像素角点检测
亚像素级角点检测的位置在摄像机标定.跟踪并重建摄像机的轨迹,或者重建被跟踪目标的三维结构时,是一个基本的测测量值. 将所求得的角点位置精确到亚像素级精度 .一个向量和与其正交的向量的点积为0,角点则满 ...
- OpenCV学习笔记(八):形态学morpholgy(2):开/闭运算,形态学梯度、顶帽/黑帽morphologyEx()
OpenCV学习笔记(八):形态学morpholgy(2):开.闭运算,形态学梯度.顶帽.黑帽:morphologyEx() 数学形态学(Mathematical morphology) 是一门建立在 ...
- 36篇博文带你学完opencv :python3+opencv学习笔记汇总目录(基础版)
经过几天的学习,opencv基础部分学习完啦.整理出来. OpenCV opencv学习笔记1:图片读入,显示与保存(有代码) opencv学习笔记2:图像处理基础 opencv学习笔记3:像素处理 ...
最新文章
- Eclipse 之 EasyExplore 插件
- 在开源模式下云计算大数据的现状浅析
- AtCoder AGC037E Reversing and Concatenating
- 初级开发人员的缺点_如何避免我作为初级开发人员犯的这7个错误
- (89)FPGA除法器设计
- 【mysql】解决MySQL GPG密钥过期问题
- Vue.js之初印象
- 异常笔记:运行hdfs copyFromLocal 上传文件报错
- 机械+固态双硬盘时机械硬盘卡顿问题解决
- python面向对象——类(上)
- 华为手机安装软件出现签名不一致
- 【智慧医疗】破解医疗数据孤岛,实现信息共享
- qtableview 查询_【转】QTableView显示数据库
- 计算机向文档中插入文本框,Word怎么插入文本框和编辑文本框
- 2. linux默认的系统管理员账号是,2019.10第二周 王俊懿_Linux
- poj 1001 Exponentiation(java)
- Idea 中的 Git 操作看这一篇就够了(最全的讲解,文章比较长,截图比较多是为了说明问题)
- 全球及中国口腔医疗行业投融资现状与与运营效益分析报告2022版
- 【线段树】【扫描线】小睿睿的方案
- Java语言的File类总结
热门文章
- 计算机房七氟丙烷气体灭火系统设计 施工安,计算机房七氟丙烷气体灭火系统的设计方案.doc...
- 一个javaweb基础的小游戏。。俄罗斯方块。。。
- PHP fpdi合并多个PDF文件,取多个PDF特定页数合并以及导出
- 盘点一些网站的反爬虫机制
- sqlite3数据库的使用
- 更改cadence617 schematic和visualizationAnalysis界面背景颜色
- 欢乐的票圈重构——九宫格控件(上)
- VMware VCP-DCV认证课程概述
- JS—随机三个0-9不重复的随机数
- Journal of Electronic Imaging 投稿分享