OpenCV————图像的基础操作

    技术2024-06-27  76

    首先导入包,读取要处理的图片

    import cv2 import numpy as np img=cv2.imread('test.jpg')#读取图片

    获取并修改像素值

    可以根据像素的行和列的坐标获取他的像素值。对 BGR 图像而言,返回值为 B,G,R 的值。对灰度图像而言,会返回他的灰度值

    # cv2.imshow('img',img) # cv2.waitKey() # cv2.destroyAllWindows() px=img[100,100]#获取图片第100行100列的像素值 print(px)#返回的是BGR的像素值 red=img[100,100,1]#0是B,1是G,2是R print(red) img[100,100]=[255,255,255]#将这个位置的像素值修改成255,255,255 print(img[100,100])

    上面这种方法被用来选取矩阵的一个区域,比如img[280:340,330:390],表示280行到340行,330到390列这一块的区域。

    获取每一个像素值,也许使用 Numpy 的 array.item() 和 array.itemset() 会更好。但是返回值是标量。如果你想获得所有 B,G,R 的值,你需要使用 array.item() 分割他们。

    print(img.item(100,100,2))#打印这个位置红色通道的像素值,它的返回值是标量 img.itemset((100,100,2),200)#将这个像素值修改为100 print(img.item(100,100,2))

    获取图像属性

    print(img.shape)#灰度图只有行列数没有通道数,可以通过形状判断是灰度图还是彩色图 print('像素数目: {}'.format(img.size))#返回图像的像素数目 print('数据类型: {}'.format(img.dtype))#返回图像数据类型 输出: (515, 960, 3) 像素数目: 1483200 数据类型: uint8

    图像ROI

    ROI(region of interest)感兴趣区域。有时你需要对一幅图像的特定区域进行操作。例如我们要检测一副图像中 眼睛的位置,我们首先应该在图像中找到脸,再在脸的区域中找眼睛,而不是直接在一幅图像中搜索。

    eye=img[110:150,150:200] img[160:200,150:200]=eye#这里修改像素值后为什么还会保留求的样子?? cv2.imshow('img',img) cv2.waitKey()

    注意:更改后的区域大小和更改前的大小要一致。比如这里原来眼睛所在位置eye=img[110:150,150:190],它的长为50px,宽40px,更改后的img[160:200,150:200]长与宽仍然要是50,40.

    疑问:img[280:340,330:390]这个区域的像素值会表现出一个球的样子,为什么在img[273:333,100:160]=ball更改像素值后还会保留球的样子,而只是将它的位置变成了[273:333,100:160]这个区域? 回答:像素值并没有改变,img[100,100]=[255,255,255]这样才是更改了像素值,这里只是更改了位置。

    拆分与合并通道

    b,g,r=cv2.split(img)#拆分通道 cv2.imshow('blue',b) cv2.imshow('green',g) cv2.imshow('red',r) cv2.waitKey()

    蓝色通道图像:

    绿色: 红色:

    img=cv2.merge(b,g,r)#合并通道

    对于同一张图像来说先拆开再合并b,g,r通道,图像不变。 另外一种提取通道的方法

    b=img[:,:,0]#提取蓝色通道 cv2.imshow('blue',b) cv2.waitKey()

    img[:,:,0]=0,使所有的蓝色通道像素值都为0,只保留绿色和红色通道。这样做可以避免先拆分通道,再合并你想保留的通道。

    图像扩边

    在图像周围填充边,这样做可以改变图像大小。 cv2.copyMakeBorder(),参数:

    src 输入图像

    top, bottom, left, right 对应边界的像素数目。

    borderType 要添加那种类型的边界,边界类型有:

    - cv2.BORDER_CONSTANT 添加有颜色的常数值边界 - cv2.BORDER_REFLECT 边界元素的镜像 - cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT - cv2.BORDER_REPLICATE 重复最后一个元素 from matplotlib import pyplot as plt r=[255,0,0] replicate = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_REPLICATE)#上下左右要填充10个像素,重复边上的像素 reflect = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_REFLECT)#镜像填充 reflect101 = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_REFLECT_101)#去掉最外一层像素的镜像填充 wrap = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_WRAP)#例如cdefgh|abcdefgh|abcdefg constant= cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_CONSTANT,value=r)#添加有颜色的边界 plt.subplot(231),plt.imshow(img,'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()

    因为使用 matplotlib 绘制,所以交换 R 和 B 的位置,OpenCV 中是按 BGR,matplotlib 中是按 RGB 排列。所以边框为红色

    Processed: 0.014, SQL: 9