目录

前言

目标

函数详解

1.获取并修改像素值

2.获取图像属性

3.图像ROI

4.拆分及合并图像通道

5.为图像扩边(填充)

参考


前言

跟着官网学习opencv-python才是基础入门的最佳选择,下文是官网的学习记录及扩展!

目标

学习读取和编辑图像像素值,使用图像ROI和其他基本操作。
        *访问图像像素值并对其进行修改
        *访问图像属性
        *设置感兴趣区域 (ROI)
        *拆分和合并图像
        *图像填充

函数详解

1.获取并修改像素值

读取一副图像,根据像素的行和列的坐标获取它的像素值,对于BGR图像而言,返回BGR的值,对于灰度图则返回灰度值
代码演示:

import cv2
img = cv2.imread('lena.png')
px=img[100,100]  # 获取坐标位置(100,100)的BGR像素值
print(px)  # [ 92  94 210]
blue = img[100,100,0]  # 仅获取蓝色通道且坐标位置是(100,100)的像素值
print(blue)  # 92
img[150,150]=[255,255,255]  # 对坐标位置(150,150)的所有通道像素赋值
print(img[150,150])  # [255 255 255]

补充:
opencv读取返回的图像数据通道顺序是BGR,而通常彩色图像通道顺序是RGB!

如果用matplotlib显示的话就会出现红色和蓝色颠倒的情况!!!

可以通过颜色通道交换再合并即可正常显示!!!

当访问彩色图像时img[height,width,channel],其中height和width分别是所访问的像素的行列数(从0开始),channel是通道编号(0对应B蓝色, 1对应G绿色, 2对应R红色)

numpy是经过优化了的进行快速数组运算的包。因此,简单地访问每个像素值并对其进行修改将非常慢,并且不鼓励这样做,而是鼓励对数组运算

例如前5行的后3列,用numpy的array.item()和array.itemset()来批量操作图像像素数组会更好。 但是返回是标量,如果想获得所有RGB的值,需要使用array.item()分割他们。
代码演示:

import cv2
img = cv2.imread('lena.png')
print(img.item(10,10,2))  # 221
img.itemset((10,10,2),100)
print(img.item(10,10,2))  # 100

2.获取图像属性

图像属性包括:行,列,通道,图像数据类型,像素数目等

img.shape可以获得图像的形状,返回值是一个包含行数,列数,通道数的元组
img.size可以返回图像的像素数目
img.dtype返回图像的数据类型,在debug时很重要,因为OpenCV-Python代码中经常出现数据类型的不一致

代码演示:

import cv2
img = cv2.imread('lena.png')
print(img.shape)  # (1088, 850, 3) 分别对应(height,width,channel)
gray_img = img[:,:,1]  # 获取灰度通道图像数据,即转成单个通道灰度图
print(gray_img.shape)  # (1088, 850)  分别对应(height,width)
# 如果图像是单通道图,返回值仅有行数和列数,所以通过检查返回值可以判断是灰度图还是彩色图
if len(gray_img.shape) == 2:
    print("Is Single Channel Image")
print(img.size)  # 2774400
print(img.dtype)  # uint8

3.图像ROI

有时,您将不得不使用图像的某些区域。对于图像中的眼睛检测,首先对整个图像进行人脸检测。
当获得人脸时,我们单独选择人脸区域并搜索其中的眼睛,而不是搜索整个图像。
它提高了准确性(因为眼睛总是在脸上:D)和性能(因为我们在小区域内搜索)。

对图像的特定区域操作。ROI是使用numpy索引来获得的。
例:选择月亮的部分并拷贝到其他区域

import cv2
img = cv2.imread('moon.jpg')
ball =img[100:200,120:220]  # 122 100 224 200
img[100:200,420:520]=ball
cv2.imshow('moon',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

python opencv 文档下载 python opencv官方文档_bc

4.拆分及合并图像通道

有时需要对BGR三个通道分别操作,这就需要拆分BGR为单个通道。有时需要把独立的通道的图片合成一个BGR。

b,g,r=cv2.split(img)#拆分
img=cv2.merge((b, g,r))#合并
#或者
b=img[:,:,0]#拆分b通道
#假如想使所有红色通道值都为0,不必拆分再赋值,可以使用numpy索引,这样更快
img[:,:,2]=0

cv2.split()是比较耗时的操作,能用numpy就尽量使用。
代码演示:

import cv2
img = cv2.imread('moon.jpg')
b, g, r = cv2.split(img)  # 拆分
img = cv2.merge((b, g, r))  # 合并
cv2.imshow('moon1', img)
cv2.waitKey(0)
b = img[:, :, 0]
g = img[:, :, 1]
r = img[:, :, 2]
img = cv2.merge((b, g, r))  # 合并
img[:, :, 2] = 0  # 将r红色通道所有像素值置0
cv2.imshow('moon2', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

5.为图像扩边(填充)

想为图像周围建一个边可以使用cv2.copyMakeBorder()函数。这经常在卷积运算或0填充时被用到。

函数介绍:

cv2.copyMakeBorder(src, top, bottom, left, right, borderType, dst=None, value=None)
src 输入图像
top,bottom,left,right   对应边界的像素数目
borderType  要添加哪种类型的边界
    cv2.BORDER_CONSTANT 添加有颜色的常数值边界,还需要下一个参数(value)
    cv2.BORDER_REFLIECT 边界元素的镜像。例如:fedcba | abcdefgh | hgfedcb
    cv2.BORDER_101或者cv2.BORDER_DEFAULT  效果举例:gfedcb | abcdefgh | gfedcba
    cv2.BORDER_REPLICATE  效果举例: aaaaaa| abcdefgh|hhhhhhh
    cv2.BORDER_WRAP  效果举例: cdefgh| abcdefgh|abcdefg
value   边界颜色(如果borderType是cv2.BORDER_CONSTANT)

代码演示:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
BLUE = [255,0,0]
img1 = cv.imread('moon.jpg')
cv2.imshow('t',img1)
b, g, r = cv2.split(img1)
img1 = cv2.merge((r, g, b))  # 由于matplotlib显示图像通道是RGB,而opencv的图像通道顺序是BGR,因此变换通道顺序以正常显示
replicate = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REPLICATE)
reflect = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT)
reflect101 = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT_101)
wrap = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_WRAP)
constant= cv.copyMakeBorder(img1,10,10,10,10,cv.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()

python opencv 文档下载 python opencv官方文档_bc_02