OpenCV-Python(9):图像基础操作

发布时间:2023年12月25日

目录

目标

获取图像像素并修改像素值

获取图像属性?

图像ROI

拆分及合并图像通道

图像边缘扩充


目标

  • 获取像素值并修改
  • 获取图像的属性(信息)
  • 图像的ROI()
  • 图像通道的拆分及合并
  • 图像扩边

获取图像像素并修改像素值

????????几乎所有这些操作与Numpy 的关系要比与OpenCV 的关系更加紧密,因此熟练Numpy 可以帮助我们写出性能更好的代码。通常可以根据像素的行和列的坐标获取他的像素值。对BGR 图像而言,返回值分别为B、G、R 的值。对灰度图像而言,会返回他的灰度值(亮度),下面代码展示如何获取图像的像素:

# 导入必要的库
import cv2
import numpy as np

# 根据图片路径读入图像
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')

# 获取某一位置三通道像素的值
px=img[100,100]
print (px)

# 获取某一位置蓝色通道的值
blue=img[100,100,0]
print (blue)


# 结果展示
## [57 63 68]
## 57

可以使用以下方式修改像素值:

img[100,100]=[255,255,255]
print (img[100,100])
# 结果如下
## [255 255 255]

?警告:Numpy 是经过优化了的快速矩阵运算的软件包。所以我不推荐逐个获取像素值并修改,这样会很慢,能有矩阵运算就不要用循环。

注意:上面提到的方法通常用来选取矩阵的一个区域,比如图像前5行的后3列。对于获取每一个像素值,也可使用Numpy 的array.item() 和array.itemset() 会更好。但是返回值是标量。如果你想获得所有B、G、R 的值,你可以使用array.item() 分割他们。

获取像素值及修改的更好方法如下:

import cv2
import numpy as np

img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')

print (img.item(10,10,2))
img.itemset((10,10,2),100)
print (img.item(10,10,2))
## 50
## 100

获取图像属性?

????????图像的属性包括:行、列、通道、图像数据类型、图像素数目等。
????????img.shape 可以获取图像的形状。他的返回回值是一个包含行数、列数、通道数的元组。

print (img.shape)
## (280, 450, 3)

?注意:如果图像是灰度图,返回值仅有行数和列数。所以通过检查这个函数返回值就可以知道加载的 是灰度图还是彩色图。

?img.size 可以返回图像的像素数目。

print (img.size)
## 378000

img.dtype 返回的是图像的数据类型.?

print (img.dtype)
## uint8

注意:在除虫(debug)时img.dtype 非常重要。因为在OpenCVPython代码中经常出现数据类型的不一致。

图像ROI

????????有时你需要对一幅图像的特定区域进行操作。例如我们要检测一副图像中眼睛的位置,我们应先应先在图像中找到脸,再在脸的区域中找眼睛,而不是直接在一幅图像中搜索,这样会提高程序的准确性和性能。ROI 也是使用Numpy 索引来获得的。现在我们􄦸选择择球的部分并把他拷贝到图像的其他区域。

import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
ball=img[280:340,330:390]
img[273:333,100:160]=bal

拆分及合并图像通道

????????有时我们需要对BGR 三个通道分别进行操作。这时你就需要把BGR 拆分成单个通道。有时你需要把独立通道的图片合并成一个BGR 图像。你可以这样做:

import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
b,g,r=cv2.split(img)
img=cv2.merge(b,g,r)

或者这样:

import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
b=img[:,:,0]

?假如你想使所有像素的红色通道值都为0,你不必先拆分再赋值。你可以直接使用Numpy 索引会更快。

import cv2
import numpy as np
img=cv2.imread('/home/duan/workspace/opencv/images/roi.jpg')
img[:,:,2]=0

?警告:cv2.split() 是一个比较耗时的操作。只有真正需要时才用它,能用Numpy 索引就尽量用。

图像边缘扩充

????????如果你想在图像周围创建一个边,就像相框一样,你可以使用cv2.copyMakeBorder()函数。这经常在卷积运算或0 填充时被用到。cv2.copyMakeBorder()函数是OpenCV中用于在图像周围创建边框的函数。该函数可以用于在图像的上、下、左、右四个方向上添加指定大小和类型的边框。

函数的语法如下:

dst = cv2.copyMakeBorder(src, top, bottom, left, right, borderType, value)

参数说明:

  • src:输入图像,可以是任意尺寸和通道数的图像。
  • top:顶部边框的大小,以像素为单位。
  • bottom:底部边框的大小,以像素为单位。
  • left:左侧边框的大小,以像素为单位。
  • right:右侧边框的大小,以像素为单位。
  • borderType:边框类型,可以是以下值之一:
    • cv2.BORDER_CONSTANT:常数边框,边框像素值为指定的value
    • cv2.BORDER_REPLICATE:复制边框,边框像素值为最边缘像素的值。
    • cv2.BORDER_REFLECT:反射边框,边框像素值沿边界反射。
    • cv2.BORDER_REFLECT_101:反射边框,边框像素值沿边界反射,但是排除边界像素。
    • cv2.BORDER_WRAP:环绕边框,边框像素值沿边界环绕。
  • value:当borderTypecv2.BORDER_CONSTANT时,用于指定边框像素值的常数。

函数返回的是添加了边框的图像。为了更好的理􄎒􄦈几种类型􄖦看下􅄑的演示程序:

import cv2
import numpy as np
from matplotlib import pyplot as plt
BLUE=[255,0,0]
img1=cv2.imread('intro.png')
replicate = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
constant= cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)
plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
plt.show()

文章来源:https://blog.csdn.net/mzl_18353516147/article/details/135190587
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。