OpenCv-python 基础图像操作

本文详细介绍了OpenCV库在图像读取、显示、保存、视频处理、ROI区域选择、通道操作、边界填充、图像加法、融合、缩放、阈值处理、平滑滤波、腐蚀膨胀、开闭运算、梯度和形状检测等方面的应用,展示了OpenCV在计算机视觉领域的强大功能。
摘要由CSDN通过智能技术生成

OpenCv

1.图像的读取

import cv2

img = cv2.imread('car.jpg')
print(type(img))

opencv中读取图像的函数是cv2.imread()

image-20240207163258793

  • filename:文件的路径
  • flags:指定读写的读取方式

flags是可选参数:

  • cv2.IMREAD_COLOR:默认参数,以彩色图像的方式加载图像,忽略任何透明度。(可用 1)
  • cv2.IMREAD_GRAYSCALE:以灰度图像的方式加载图像。(可用 0)
  • cv2.IMREAD_UNCHANGED以原始图像的方式加载图像。(可用-1)

注意:OpenCv以彩色图像读取的时候是BGR

2.图像的显示

import cv2

img = cv2.imread('../png/01_cat.jpg' , 1)
cv2.imshow('cat',img)
# 等待时间,毫秒级,0表示任意键终止,5000ms表示5s
cv2.waitKey(0)
# 销毁图像窗口
cv2.destroyAllWindows()

image-20240207164150737

  • winname:展示图像的窗口名字
  • mat:所展示的图像

这里我们封装一个函数,方便展示图像

# 绘图显示(封装函数)
def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

下文所用的的cv_show(),就是这边封装的函数。

3.图像的保存

img = cv2.imread('cat01.jpg' , 1)
cv2.imwrite('cat02.jpg',img)

image-20240207164514365

  • filename:保存的路径。
  • img:保存的图像。
  • params:用于指定保存图像的特定格式参数。它可以是 JPEG、PNG 等图像格式的特定参数。

4.视频处理

vc = cv2.VideoCapture(0)
if vc.isOpened():
    open,img = vc.read()# 这里的 vc.read() 相当于读取图像的第一帧
                        # 若循环不断的执行 vc.read,则不断的读取第二帧、第三帧....
        				#open:是否被打开 img:图像
    cv_show('img',img)

cv2.VideoCapture 函数可以捕获摄像头,或读取视频文件。

cv2.VideoCapture 函数入口参数:

  • 用数字来控制不同的设备(摄像头),例如 0、1。
  • 如果是视频文件,直接指定好路径即可。

5.ROI区域

5.1 位置提取

img = cv2.imread('cat.jpg')
cat = img[0:200,0:200] # 选择图片感兴趣的区域
cv_show('cat',cat)

切片显示图片中左上角的一个 200x200 大小的区域,

5.2 通道提取

img = cv2.imread('cat.jpg')
b,g,r = cv2.split(img)
cv_show('cat_b',b)
print('b.shape:',b.shape) # B通道,单通道,灰度图
cv_show('cat_g',g)
print('g.shape:',g.shape) # G通道,单通道,灰度图
cv_show('cat_r',r)
print('r.shape:',r.shape) # R通道,单通道,灰度图
img = cv2.merge((b,g,r))
print('img.shape:',img.shape) # 3 通道,彩色图

6.边界填充

img = cv2.imread('cat.jpg')

top_size,bottom_size,left_size,right_size = (50,50,50,50)  # 填充多少区域

# 最后一个入口参数为填充方式

# 方式一:复制法
replicate = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REPLICATE) 
# 方式二:反射法
reflect = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REFLECT)
# 方式三:反射法二(不要最边缘的像素)
reflect101 = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REFLECT_101)      
# 方式四:外包装法
wrap = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_WRAP)
# 方式五:常量法
constant = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_CONSTANT,value=0)

image-20240207170611190

image-20240207170652815

  • src:图像
  • topbottomleftright:分别指定了上、下、左、右四个方向上的边框大小。
  • borderType:
    • BORDER_REPLICATE:复制法,也就是复制最边缘像素。
    • BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
    • BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
    • BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
    • BORDER_CONSTANT:常量法,常数值填充。

7.图像的加法

7.1 直接相加

img_cat = cv2.imread('cat.jpg')
img_dog = cv2.imread('dog.jpg')

img_cat2 = img_cat + 10 # 将 img_cat 矩阵中每一个值都加 10
print(img_cat[:5,:,0])
print(img_cat2[:5,:,0])
print((img_cat+img_cat2)[:5,:,0])  # 0-255 若相加越界后 294 用 294%256 获得余数 38  

7.2 add()

image-20240207171321814

  • src1:第一幅输入图像。
  • src2:第二幅输入图像。
  • dst:可选参数,用于指定输出图像。如果不提供此参数,函数会创建一个与输入图像相同大小和类型的输出图像。
  • mask:可选参数,用于指定掩码图像。只有掩码中对应位置的像素才会参与运算。
  • dtype:可选参数,指定输出图像的数据类型。

cv2.add() 函数将两幅输入图像的对应像素值相加,并将结果写入输出图像中。如果相加的结果超出了像素值的范围,会进行截断(即超出 255 的部分会被截断为 255)。

8.图像的融合

8.1 图像变化

不同数据大小的图像不能进行数值操作

image-20240207171538967

  • src:输入图像。
  • dsize:输出图像的尺寸,可以是一个元组 (width, height) 或者一个整数。
  • dst:可选参数,用于指定输出图像。如果不提供此参数,函数会创建一个与指定尺寸相同的输出图像。
  • fxfy:可选参数,用于指定沿水平和垂直方向的缩放比例。如果指定了 fxfy,则忽略 dsize 参数。
  • interpolation:可选参数,指定插值方法。可以是以下值之一:
    • cv2.INTER_NEAREST:最近邻插值。
    • cv2.INTER_LINEAR:双线性插值(默认值)。
    • cv2.INTER_CUBIC:三次样条插值。
    • cv2.INTER_AREA:区域插值。
    • cv2.INTER_LANCZOS4:Lanczos 插值。
import cv2

# 读取图像
img = cv2.imread('image.jpg')

# 指定输出图像的尺寸
resized_img = cv2.resize(img, (400, 300))
cv_show(resized_img)

8.2 图像融合

res = cv2.addWeighted(img_cat,0.4,img_dog,0.6,0) # img_cat 的权重为 0.4,img_dog 的权重为 0.6 
print(img_dog.shape)
cv_show(res)

cv2.addWeighted() 是 OpenCV 中用于图像混合的函数。它可以将两幅图像按照权重进行线性组合,生成一幅新的图像。

image-20240207172625701

  • src1:第一幅输入图像。
  • alpha:第一幅图像的权重。
  • src2:第二幅输入图像。
  • beta:第二幅图像的权重。
  • gamma:图像的亮度增益。
  • dst:可选参数,用于指定输出图像。
  • dtype:可选参数,指定输出图像的数据类型。

d s t = s r c 1 ∗ a l p h a + s r c 2 ∗ b e t a + g a m m a dst = src1 * alpha + src2 * beta + gamma dst=src1alpha+src2beta+gamma

alphabeta 分别指定了两幅图像的权重,gamma 指定了图像的亮度增益。如果 gamma 为零,则不进行亮度调整。

9.图像的缩放

9.1 倍数缩放

img = cv2.imread('cat.jpg') 
res = cv2.resize(img,(0,0),fx=3,fy=1) # (0,0)表示不确定具体值,fx=3 相当于行像素 x 乘 3,fy=1 相当于 y 乘 1 
cv_show('res',res)
9.2 等比例缩放
res = cv2.resize(img,(0,0),fx=1.5,fy=1.5) # 同比例放缩
cv_show('res',res)

10.图像的阈值

img = cv2.imread('cat.jpg',cv2.IMREAD_COLOR)  
img_gray = cv2.imread('01_Picture/01_cat.jpg',cv2.IMREAD_GRAYSCALE)    
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)    
print(ret)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV) # THRESH_BINARY_INV 相对 THRESH_BINARY 黑的变成白的,白的变成黑的       
print(ret)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)     
print(ret)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
print(ret)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
print(ret)

titles = ['original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']        
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]  

for i in range(6):
    plt.subplot(2,3,i+1), plt.imshow(images[i],'gray')  
    plt.title(titles[i])
    plt.xticks([]),plt.yticks([])
plt.show()

image-20240207173418575

image-20240207173437284

  • src:输入图像,必须是单通道图像(灰度图)。
  • thresh:设定的阈值,用于将像素值分为两类。
  • maxval:当像素值高于阈值时,设置的最大值。
  • type:阈值化类型,包括以下几种:
    • cv2.THRESH_BINARY:二值化,大于阈值的像素值设为 maxval,小于等于阈值的像素值设为 0。
    • cv2.THRESH_BINARY_INV:反二值化,大于阈值的像素值设为 0,小于等于阈值的像素值设为 maxval
    • cv2.THRESH_TRUNC:截断,大于阈值的像素值设为阈值,小于等于阈值的像素值不变。
    • cv2.THRESH_TOZERO:设为零,大于阈值的像素值不变,小于等于阈值的像素值设为 0。
    • cv2.THRESH_TOZERO_INV:反设为零,大于阈值的像素值设为 0,小于等于阈值的像素值不变。
  • dst:可选参数,用于指定输出图像。

11.图像的平滑处理

图像的平滑处理是一种常见的图像处理技术,用于减少图像中的噪声并模糊图像。常见的平滑处理方法包括均值滤波、方框滤波、高斯滤波、中值滤波等。

11.1 均值滤波

将图像中每个像素的值替换为其周围像素值的平均值。这种方法对去除轻微的噪声很有效,但可能会使图像变得模糊。

# 均值滤波
# 简单的平均卷积操作,方框中的值相加,取平均,替换掉中心204的值

blur = cv2.blur(img,(3,3)) # (3,3) 为核的大小,通常情况核都是奇数 3、5、7

11.2 方框滤波

使用一个归一化的方形卷积核对图像进行平滑处理。该滤波器的每个元素都具有相同的权重,即均值滤波器

# 方框滤波
# 基本和均值一样,可以选择归一化

# 在 Python 中 -1 表示自适应填充对应的值,这里的 -1 表示与颜色通道数自适应一样
box = cv2.boxFilter(img,-1,(3,3),normalize=True)  # 方框滤波如果做归一化,得到的结果和均值滤波一模一样

11.3 高斯滤波

在均值滤波的基础上,不同的像素具有不同的权重,距离越近的像素权重越高。这种方法更有效地保留图像的边缘信息。

# 高斯函数,越接近均值时,它的概率越大。
# 离中心值越近的,它的权重越大,离中心值越远的,它的权重越小。

aussian = cv2.GaussianBlur(img,(5,5),1)

11.4 中值滤波

将每个像素的值替换为其邻域像素的中值。对于去除椒盐噪声(即图像中突然出现的白点或黑点)非常有效。

# 中值滤波
# 排序后拿中值替代中间元素值的大小

median = cv2.medianBlur(img,5)

11.5 效果

image-20240207175011025

12. 腐蚀与膨胀

12.1 腐蚀操作

腐蚀操作会将图像中的前景对象(白色区域)进行收缩,即使前景对象变小或者消失。这种操作可以移除小的白色噪声,断开图像中的连接部分,以及消除窄的通道。

12.2 膨胀操作

膨胀操作与腐蚀相反,会将图像中的前景对象进行膨胀,使得前景对象变大或者连接。这种操作可以填充图像中的孔洞、连接被断开的对象,以及扩展对象的大小。

eroded_img = cv2.erode(src, kernel, iterations=1)
dilated_img = cv2.dilate(src, kernel, iterations=1)

  • src:输入图像,通常为二值图像,其中前景为白色,背景为黑色。
  • kernel:形态学操作的内核,控制操作的形状和大小。
  • iterations:形态学操作的迭代次数,默认为 1

腐蚀和膨胀操作通常是拿二值图像做腐蚀操作

# 读取图像
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# 创建腐蚀和膨胀的内核
kernel = np.ones((5, 5), np.uint8)

# 腐蚀操作
eroded_img = cv2.erode(img, kernel, iterations=1)

# 膨胀操作
dilated_img = cv2.dilate(img, kernel, iterations=1)

13.开运算与闭运算

13.1 开运算与闭运算

开运算(Opening)和闭运算(Closing)是图像处理中常用的形态学操作,通常用于去除图像中的噪声、填充孔洞或连接图像中的断裂部分。

  1. 开运算(Opening):先对图像进行腐蚀操作,再进行膨胀操作。开运算能够消除小的白色噪声,同时保持图像中较大对象的形状和结构。它通常用于去除图像中的噪声和细小的对象,以及分离连接的对象。
  2. 闭运算(Closing):先对图像进行膨胀操作,再进行腐蚀操作。闭运算能够填充图像中的孔洞,连接断裂的对象,以及平滑图像中对象的边界。它通常用于填充图像中的小孔洞和连接断裂的对象。

在 OpenCV 中,可以使用 cv2.morphologyEx() 函数来应用开运算和闭运算。这个函数提供了一个 op 参数,用于指定所需的形态学操作。

image-20240207180030524

  • src:输入图像,通常为二值图像。
  • op:指定形态学操作的类型,可以是 cv2.MORPH_OPEN(开运算)或 cv2.MORPH_CLOSE(闭运算)。
  • kernel:形态学操作的内核,控制操作的形状和大小。

13.2 梯度运算

形态学梯度是膨胀图像减去腐蚀图像的结果,用于检测图像中的边缘。它可以通过以下方式进行计算:

g r a d i e n t = d i l a t e d i m g − e r o d e d i m g gradient=dilated_img−eroded_img gradient=dilatedimgerodedimg

# 梯度 = 腐蚀-膨胀
pie = cv2.imread('pie.png')

kernel = np.ones((7,7),np.uint8)
dilate = cv2.dilate(pie,kernel,iterations=5) 
erosion = cv2.erode(pie,kernel,iterations=5) 

14.礼帽与黑帽

14.1 礼帽

礼帽操作是原始图像与图像的开运算之间的差值。开运算能够消除图像中的噪声,平滑图像的背景,因此礼帽操作可以用来突出图像中的小亮点和细微结构。礼帽操作通常用于检测图像中的亮度变化或者局部结构。

# 读取图像
img = cv2.imread('Dige.jpg', cv2.IMREAD_GRAYSCALE)

# 创建形态学操作的内核
kernel = np.ones((5, 5), np.uint8)

# 礼帽操作
tophat_img = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

14.2 黑帽

黑帽操作是图像的闭运算与原始图像之间的差值。闭运算能够填充图像中的孔洞,连接断裂的对象,因此黑帽操作可以用来突出图像中的暗部分或者凹陷结构。黑帽操作通常用于检测图像中的暗度变化或者局部结构。

# 黑帽操作
blackhat_img = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

image-20240207180903571

  • op:

    • cv2.MORPH_OPEN:开运算(Opening)操作。

    • cv2.MORPH_CLOSE:闭运算(Closing)操作。

    • cv2.MORPH_GRADIENT:形态学梯度(Morphological Gradient)操作。

    • cv2.MORPH_TOPHAT:礼帽(Top Hat)操作。

  • 22
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值