【opencv系列07】OpenCV4.X图像基本操作

本文详细介绍了如何在OpenCV中通过坐标访问像素值,包括BGR图和灰度图的不同处理;探讨了图像的基本属性如尺寸、通道数和数据类型;并通过ROI技术聚焦处理感兴趣区域,并展示了通道拆分、图像边框操作实例。
摘要由CSDN通过智能技术生成

点击上方“AI搞事情”关注我们


一、像素操作

可以通过行列坐标访问像素值,对于BGR图,返回一个蓝色、绿色、红色通道的数组值,对于灰度图,仅返回相应的强度值。

代码

import cv2
img = cv2.imread('image.jpg')
px = img[32,32] # 访问(32,32)坐标像素值
print(px)
print(img[32,32,0]) # 访问B通道像素值
print(img[32,32,1]) # 访问G通道像素值
img[32,32] = [108, 108, 108] # 修改像素值
print(img[32,32])

输出

[ 93 136 145]
93
136
[108 108 108]

Note

  • Numpy是一个用于快速阵列计算的优化库。因此,简单地访问每个像素值并对其进行修改将非常缓慢。

  • 上述方法通常用于选择数组的一个区域,比如前五行和三列,对于访问单个像素点,推荐使用array.item()array.itemset(),它们返回的是一个标量。如果需要访问所有B,G,R值,需要对它们单独调用array.item()

代码

import cv2
img = cv2.imread('image.jpg')
p = img.item(32,32,2) # 访问R值
print(p)
img.itemset((32,32,2),100) # 修改R值
p = img.item(32,32,2)
print(p)

输出

145
100

二、图像属性

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

import cv2
img = cv2.imread('image.jpg')
 
print(img.shape)  #图像的形状,返回值是一个包含行数(高)、列数(宽)、通道数的元组。
print(img.size)   #图像的像素数目。
print(img.dtype)  #图像的数据类型。

输出

(640, 1024, 3)
1966080
uint8

Note

  • 注意如果图像是灰度图像,img.shape返回的元组仅包含行数和列数,因此它是一种检查图像是灰度图像还是彩色图像的好方法。

  • img.dtype在调试时非常重要,因为OpenCV-Python代码中的大量错误是由无效的数据类型引起的。

三、图像ROI

ROI (region of interest, 感兴趣区域)是从图像中选择的一个图像区域,这个区域是你的图像分析所关注的重点。圈定该区域以便进行进一步处理。使用ROI圈定你想处理的目标,可以减少处理时间,增加精度。比如:对于图像中的眼睛检测,在整个图像上进行第一次面部检测。当获得面部时,我们单独选择面部区域并在其内部搜索眼睛而不是搜索整个图像。

选择图像ROI并将其复制到图像中的另一个区域

代码

import cv2
img = cv2.imread('image.jpg')

husky = img[1:240,60:270]
img[61:300,270:480] = husky

cv2.imshow('show',img)
cv2.waitKey()

四、通道拆分

B,G,R三通道含有不同的颜色信息,有时需要将通道分离,在单个通道进行操作。有两种通道分离的方式:

  • cv2.split函数

import cv2
img = cv2.imread('img.jpg')
b,g,r = cv2.split(img) #拆分图像通道
img = cv2.merge((b,g,r))
  • numpy切片

b = img[:,:,0]

单通道所有像素置零

img[:,:,2] = 0

NOTE:
cv2.split()相对比较耗时,必要时才使用。否则建议使用Numpy索引。

五、图像边框

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

src:输入图像
topbottomleftright:相应方向上像素数的边框宽度
value :
cv2.BORDER_CONSTANT
cv2.BORDER_REFLECT
cv2.BORDER_REFLECT_101 or cv2.BORDER_DEFAULT
cv2.BORDER_REPLICATE
cv2.BORDER_WRAP

不同value效果代码

import cv2
from matplotlib import pyplot as plt

BLUE = [255,0,0]

img1 = cv2.imread('image.jpg')

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()

六、应用

1. 获取图像ROI并拼接在原图下方

代码

import cv2
import numpy as np

img1 = cv2.imread('image.jpg')
img2 = img1[200: 500, 300:650, :]

w = max(img1.shape[1], img2.shape[1])
h = img1.shape[0] + img2.shape[0]

merge_img = np.zeros((h, w, 3), dtype=np.uint8)
merge_img[:img1.shape[0], :img1.shape[1]] = img1
merge_img[img1.shape[0]:, :img2.shape[1]] = img2
cv2.imwrite('res.jpg', merge_img)
cv2.imshow('img', merge_img)
cv2.imshow('img2', img1)
cv2.waitKey(0)

2. 利用通道分离去除票据红色印章

代码

import cv2

th = 180  # 二值化阈值
src = cv2.imread('image.jpg')
blue, green, red = cv2.split(src)
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, th, 255, cv2.THRESH_BINARY)

_, red_binary = cv2.threshold(red, th, 255, cv2.THRESH_BINARY)
cv2.imshow("src", src)
cv2.imshow("gray", gray)
cv2.imshow("binary", binary)
cv2.imshow("red channel", red)
cv2.imshow("blue channel", blue)
cv2.imshow("green channel", green)
cv2.imshow("red+binary", red_binary)

new_img = cv2.merge((blue, green, red_binary))
cv2.imshow("new image", new_img)
cv2.waitKey(0)
原图
灰度图
红色通道图
红色通道二值化结果


参考:如何去除票据上的印章: https://www.cnblogs.com/skyfsm/p/7638301.html

往期推荐

长按二维码关注我们

有趣的灵魂在等你

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值