Python OpenCV 针对图像细节的不同操作技巧

本系列专栏写作将采用首创的问答式写作形式,快速让你学习到 OpenCV 的初级、中级、高级知识。

6. 在 Python OpenCV 针对图像细节的不同操作

本篇博客的目标将为你解释一幅图像的拆解,包括图像像素的说明,图像属性信息的获取与修改,
图像目标区域 ROI 相关内容,以及图像通道的知识(包括拆分通道和合并通道)

这些内容在知识结构上与 numpy 库十分紧密,如果从学习的角度出发,建议你储备一下 numpy 相关知识。

读取修改图像的像素值

在之前的博客中,我们已经学到了如何读取一幅图像,使用 cv2.imread 函数即可,并且掌握了该函数的两个关键参数。

读取图片之后,我们可以直接使用操作数组的方式获取图像任意位置的颜色,一般这个颜色的默认顺序是 BGR。

测试代码如下:

import cv2
import matplotlib.pyplot as plt

src = cv2.imread("./6_test.jpg")

# 获取 100 x 100 位置的像素值
print(src[100, 100])

cv2.imshow("src", src)

cv2.waitKey()

这里首先获取 100 x 100 位置的像素值。
src[100,100]会获取到三个值,分别对应的 BGR 通道的值。我们在图片上标记一个像素点,rows = 250,cols=470 ,接下来修改上述代码,看获取到的 BGR 值。

import cv2
import matplotlib.pyplot as plt

src = cv2.imread("./6_test.jpg")

# 注意获取像素值的格式为 [cols,rows]
print(src[250, 470])

cv2.imshow("src", src)

cv2.waitKey()

上文特别注意的就是,获取像素值的格式为 [cols,rows],列在前,行在后。

以上获取到的是 BGR 值,也可以只获取单个通道的值,对应的代码是 [cols,rows,channel],对应到代码部分,如下所示:

# 获取蓝色通道值
print(src[250, 470, 0])

蓝色通道对应 0,绿色通道为 1,红色通道为 2,超出以上三个值,就会出现如下错误:

IndexError: index 3 is out of bounds for axis 2 with size 3

当前如果你直接读取了灰度图,例如下述代码,三个通道的值是相同的。

import cv2
import matplotlib.pyplot as plt

src = cv2.imread("./6_test.jpg", 0)

# 注意获取像素值的格式为 [cols,rows]
print(src[250, 470])

cv2.imshow("src", src)

cv2.waitKey()

这个地方还有一个编码上存在的潜在问题,如果读取的是四通道图片,即图片有透明度,那数组的索引值可以读取到 3,也就是下述代码是正确的。

import cv2
import matplotlib.pyplot as plt

src = cv2.imread("./test.jpg", -1)

# 注意获取像素值的格式为 [cols,rows]
print(src[250, 470, 3])

cv2.imshow("src", src)

cv2.waitKey()

src[250, 470, 3] 成功读取到了透明通道的值。

我们可以针对特定的像素点进行值的修改,例如下述代码

import cv2
import matplotlib.pyplot as plt

src = cv2.imread("./6_test.jpg")

# 注意获取像素值的格式为 [cols,rows]
src[250, 470] = [255, 255, 255]

cv2.imshow("src", src)

cv2.waitKey()

注意下图的红色箭头指向的位置,出现一个白色亮点,使用该办法,可以制造出一个【椒盐图片】。

这个地方需要注意的一个潜在 BUG,读取图片的通道数,决定了你复制时数组元素个数,例如下述代码将会报错。

import cv2
import matplotlib.pyplot as plt

src = cv2.imread("./6_test.jpg")

# 注意获取像素值的格式为 [cols,rows]
src[250, 470] = [255, 255, 255, 255]

cv2.imshow("src", src)

cv2.waitKey()

错误信息都是类似的,提示数组维度不同。

ValueError: cannot copy sequence with size 4 to array axis with dimension 3

最后一点使用以上方式操作图像的像素点,非常耗时,因为一张图片的像素点数据是非常大的,一般情况下能用 numpy 集成好的方法,就不要用这种最笨拙的方式。

使用 numpy 获取通道值,注意该方式获取的是标量,如果你想获得所有 BGR 的值,你需要使用 array.item() 依次获取。

import cv2
import numpy as np

src = cv2.imread("./6_test.jpg")
print(src[100, 100])
b = src.item(100, 100, 0)
g = src.item(100, 100, 1)
r = src.item(100, 100, 2)
print(b, g, r)

cv2.imshow("src", src)
cv2.waitKey()

如果希望设置该值,直接使用 itemset 函数即可。

src.itemset((100, 100, 0), 200)
print(src[100, 100])

可以任意寻找一张图片进行对应的测试,运行效果如下:

[ 31 68 118]
31 68 118
[200 68 118]

OpenCV 中图像属性常见问题解析

对于一幅图像,除了像素矩阵以外,还有一个非常重要的内容,是图像的属性,这些包括行、列、通道、数据类型,像素数量、图像形状等内容。

例如,我们经常使用 img.shape 去获取图像的形状,尤其注意的是,返回的内容是行数(rows),列数(cols),以及通道数(channels),并且返回值类型是一个元组。

如果你读取图像的时候,设置紧读取灰度图,那只会返回行数和列数,相应的通过这个值很容易能判断出你加载的图像类型。

例如下述代码,通过不同的方式读取同一张图片,输出图像的不同形状。

import cv2
import numpy as np

# 选择一个 jpg 图片,可以读取到不同的通道
src1 = cv2.imread("./test.jpg", -1)
src2 = cv2.imread("./test.jpg", 0)
src3 = cv2.imread("./test.jpg")
# 四通道,包含透明通道
print(src1.shape)
# 灰度图
print(src2.shape)
# 三通道
print(src3.shape)

输出结果可以快速的读取出图像是彩色图像还是灰度图像。

(397, 595, 4)
(397, 595)
(397, 595, 3)

使用 img.size 可以快速返回图像中像素的合计数目,测试代码如下:

# 选择一个 jpg 图片,可以读取到不同的通道
src1 = cv2.imread("./test.jpg", -1)
src2 = cv2.imread("./test.jpg", 0)
src3 = cv2.imread("./test.jpg")
# 四通道,包含透明通道
print(src1.shape)
print(src1.size)
# 灰度图
print(src2.shape)
print(src2.size)
# 三通道
print(src3.shape)
print(src3.size)

我们依旧三种不同的读取方式,读取到的像素数分别如下:

(397, 595, 4)
944860
(397, 595)
236215
(397, 595, 3)
708645

注意,灰度图像和彩色图像的像素数不同,它们之前存在如下关系。

灰度图像的像素数 = 行数 x 列数 = 397 x 595 = 236215

彩色图像的像素数 = 行数 x 列数 x 通道数 = 944860 (四通道)/ 708645(三通道)

使用 img.dtype 属性可以获取到图像的类型,具体如下:

print(src1.dtype)

这里读取到的值,都是相同的 uint8 表示 8 位图像,这里可以记住只要是 uint8 格式,那对应的 BGR 值的范围就是在 [0,255] 之间。

在操作上述属性值的时候,会出现如下 BUG,该 BUG 的通用解决方案是排查图片是否正常读取,需要特别注意下:

AttributeError: 'NoneType' object has no attribute 'shape'
print(src1.dtype)

这里读取到的值,都是相同的 uint8 表示 8 位图像,这里可以记住只要是 uint8 格式,那对应的 BGR 值的范围就是在 [0,255] 之间。

在操作上述属性值的时候,会出现如下 BUG,该 BUG 的通用解决方案是排查图片是否正常读取,需要特别注意下:

AttributeError: 'NoneType' object has no attribute 'shape'

到此这篇关于Python OpenCV 针对图像细节的不同操作的文章就介绍到这了,更多相关Python OpenCV图像内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python opencv 实现读取、显示、写入图像的方法

    opencv是一个强大的图像处理和计算机视觉库,实现了很多实用算法,值得学习和深究下. opencv包安装 · 这里直接安装opencv-python包(非官方): pip install opencv-python 官方文档:https://opencv-python-tutroals.readthedocs.io/en/latest/ 1.读取图像 import cv2 image=cv2.imread("dog2.jpg",1) 说明: 第二个参数是一个标志,它指定了读取图像的方

  • Python+OpenCV实现将图像转换为二进制格式

    在学习tensorflow的过程中,有一个问题,tensorflow在训练的过程中读取的是二进制图像数据库文件,而不是图像文件,因此 在进行训练.测试之前需要将图像文件转换为二进制格式. 下面是我在ubuntu中使用python+OpenCV读取图像并转换为二进制格式文件的代码. #coding=utf-8 ''' Created on 2016年3月24日 使用Opencv读取图像将其保存为二进制格式文件,再读取该二进制文件,转换为图像进行显示 @author: hanchao ''' imp

  • OpenCV利用python来实现图像的直方图均衡化

    1.直方图 直方图: (1) 图像中不同像素等级出现的次数 (2) 图像中具有不同等级的像素关于总像素数目的比值. 我们使用cv2.calcHist方法得到直方图 cv2.calcHist(images, channels, mask, histSize, ranges): -img: 图像 -channels: 选取图像的哪个通道 -histSize: 直方图大小 -ranges: 直方图范围 cv2.minMaxLoc: 返回直方图的最大最小值,以及他们的索引 import cv2 impo

  • Python+OpenCV图像处理——图像二值化的实现

    简介:图像二值化就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程. 普通图像二值化 代码如下: import cv2 as cv import numpy as np #全局阈值 def threshold_demo(image): gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) #把输入图像灰度化 #直接阈值化是对输入的单通道矩阵逐像素进行阈值分割. ret, binary = cv.threshold(gray

  • Python+OpenCV实现图像的全景拼接

    本文实例为大家分享了Python+OpenCV实现图像的全景拼接的具体代码,供大家参考,具体内容如下 环境:python3.5.2 + openCV3.4 1.算法目的 将两张相同场景的场景图片进行全景拼接. 2.算法步骤 本算法基本步骤有以下几步: 步骤1:将图形先进行桶形矫正 没有进行桶形变换的图片效果可能会像以下这样: 图片越多拼接可能就会越夸张. 本算法是将图片进行桶形矫正.目的就是来缩减透视变换(Homography)之后图片产生的变形,从而使拼接图片变得畸形. 步骤2:特征点匹配 本

  • Python+OpenCV图像处理——实现直线检测

    简介: 1.霍夫变换(Hough Transform) 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法.主要用来从图像中分离出具有某种相同特征的几何形状(如,直线,圆等).最基本的霍夫变换是从黑白图像中检测直线(线段). 2.Hough变换的原理是将特定图形上的点变换到一组参数空间上,根据参数空间点的累计结果找到一个极大值对应的解,那么这个解就对应着要寻找的几何形状的参数(比如说直线,那么就会得到直线的斜率k与常熟b,圆就会得到圆心与半径等等) 3.霍夫线变

  • Python OpenCV中的numpy与图像类型转换操作

    Python OpenCV存储图像使用的是Numpy存储,所以可以将Numpy当做图像类型操作,操作之前还需进行类型转换,转换到int8类型 import cv2 import numpy as np # 使用numpy方式创建一个二维数组 img = np.ones((100,100)) # 转换成int8类型 img = np.int8(img) # 颜色空间转换,单通道转换成多通道, 可选可不选 img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) cv2

  • Python OpenCV 针对图像细节的不同操作技巧

    本系列专栏写作将采用首创的问答式写作形式,快速让你学习到 OpenCV 的初级.中级.高级知识. 6. 在 Python OpenCV 针对图像细节的不同操作 本篇博客的目标将为你解释一幅图像的拆解,包括图像像素的说明,图像属性信息的获取与修改, 图像目标区域 ROI 相关内容,以及图像通道的知识(包括拆分通道和合并通道) 这些内容在知识结构上与 numpy 库十分紧密,如果从学习的角度出发,建议你储备一下 numpy 相关知识. 读取修改图像的像素值 在之前的博客中,我们已经学到了如何读取一幅

  • Python+OpenCV实现基本的图像处理操作

    目录 模块的安装 图片的各种操作 读取图像 展示图像 图片保存 图片的各种属性 图像的基本操作 今天小编来和大家分享一下Python在图像处理当中的具体应用,那既然是图像处理,那必然要提到opencv模块了,该模块支持与计算机视觉和机器学习相关的众多算法,并且应用领域正在日益扩展,大致有以下几种领域 物体识别:通过视觉以及内部存储来进行物体的判断 图像分割 人脸识别 汽车安全驾驶 人机交互 等等 当然这次小编并不打算将这么高深的内容,今天就从最基本的opencv模块在图像的基本操作上说起 模块的

  • 深入学习Python+Opencv常用四种图像处理操作

    目录 改变色彩空间: cv.cvtColor() 改变图像大小:cv.resize() 二维卷积操作 常用模糊 opencv图像处理(深度学习中常用的) 改变色彩空间: cv.cvtColor() cv.cvtColor(img, flag) img:原图像 flag:要改变的类型 常用的flag有:cv.COLOR_BGR2GRAY (BGR->GRAY).cv.COLOR_BGR2HSV img = cv.imread(r'E:\0_postgraduate\test.jpg') gray

  • Python OpenCV对图像像素进行操作

    目录 遍历并修改图像像素值 图像的加减乘除运算 遍历并修改图像像素值 在使用opencv处理图像时,有时需要对图像的每个像素点进行处理,比如取反.修改值等操作,就需要通过h和w遍历像素.依然以下图为例: 具体代码: import cv2 as cv import numpy as np def image_pixel(image_path: str): img = cv.imread(image_path, cv.IMREAD_COLOR) cv.imshow('input', img) h,

  • 详解Python+OpenCV进行基础的图像操作

    目录 介绍 形态变换 腐蚀 膨胀 创建边框 强度变换 对数变换 线性变换 去噪彩色图像 使用直方图分析图像 介绍 众所周知,OpenCV是一个用于计算机视觉和图像操作的免费开源库. OpenCV 是用 C++ 编写的,并且有数千种优化的算法和函数用于各种图像操作.很多现实生活中的操作都可以使用 OpenCV 来解决.例如视频和图像分析.实时计算机视觉.对象检测.镜头分析等. 许多公司.研究人员和开发人员为 OpenCV 的创建做出了贡献.使用OpenCV 很简单,而且 OpenCV 配备了许多工

  • Python opencv应用实现图片切分操作示例

    目录 说明 操作说明 代码 切换效果 说明 之前下载来zip包的漫画,里面的图片都是两张一起的: 但是某些漫画查看软件不支持自动分屏,看起来会比较不舒服,所以只能自己动手来切分. 操作说明 Python有不少的库支持图片操作,其中比较著名的一个是OpenCV. OpenCV是一个跨平台的计算机视觉库,Python下有它的接口实现. Python默认不带OpenCV,所以需要先用pip下载: OpenCV功能强大,这里用来做图片的切分其实是牛刀小试. 关于OpenCV的功能,这里不多介绍,有兴趣的

  • Python Django ORM连表正反操作技巧

    一.A表男生,B表女生,C表关系 1通过A表查与某个男生有关系的所有女生 思想1:在A表中确认男生后,通过反查到C表,获取相关内容(QuerySet),然后再跨到B表获取所有女生信息. obj=models.Boy.objects.filter(name='陈亮').first() love_list=obj.love_set.all() #love_set.all()反查相关所有(跨表) for i in love_list: #每个i是一个Love的对象,里面有一个id有一个nick pri

  • Python实现针对json中某个关键字段进行排序操作示例

    本文实例讲述了Python实现针对json中某个关键字段进行排序操作.分享给大家供大家参考,具体如下: 示例: json_array = [{"time":20150312,"value":"c"}, {"time":20150301,"value":"a"}, {"time":20150305,"value":"b"}] js

  • python针对Oracle常见查询操作实例分析

    本文实例讲述了python针对Oracle常见查询操作.分享给大家供大家参考,具体如下: 1.子查询(难): 当进行查询的时候,发现需要的数据信息不明确,需要先通过另一个查询得到, 此查询称为子查询: 执行顺序:先执行子查询得到结果以后返回给主查询 组成部分: 1).主查询部分 2).子查询部分 [注意事项]: 子查询一定需要被定义/包裹在小括号内部,可以认为是显示的提升了代码执行的优先级 需求1: 查询薪资比Abel的高的有谁? 分析: ①.先查询出Abel的薪资是多少? ②.将过滤条件定义为

  • Python中文件I/O高效操作处理的技巧分享

    如何读写文本文件? 实际案例 某文本文件编码格式已直(如UTF-8,GBK,BIG5),在python2.x和python3.x中分别如何读取这些文件? 解决方案 字符串的语义发生了变化: python2 python3 str bytes unicode str python2.x 写入文件前对 unicode 编码,读入文件后对二进制字符串解码 >>> f = open('py2.txt', 'w') >>> s = u'你好' >>> f.wri

随机推荐