opencv学习记录

本文介绍了使用OpenCV进行图像基本操作,包括读取、显示图像,分析图片参数,转换为灰度图,保存图片,计算像素,截取部分图像数据,以及分离和合并颜色通道。此外,还详细讨论了边界填充的几种方法,并展示了形态学操作,如腐蚀、膨胀、开运算、闭运算及其应用。最后,提到了在处理过程中遇到的常见错误及解决办法。
摘要由CSDN通过智能技术生成

今天开始系统的过一遍OpenCv的流程,opencv处理图像很强大,下面记录学习过程

一. 图像基本操作

1.图片数据读取

如上代码,要注意的地方是图片路劲是英文路径!!!

cv2.imshow('image', img) # 图像的显示,也可以创建多个窗口

其中参数'image'是显示窗口的标题

上述代码可以打包成一个函数,方便后续调用,也让代码可读性增加

2.图片参数分析

利用代码:print(img.shape, img1.shape)输出图片的尺寸

输出结果:(900, 900, 3) (1080, 1920, 3)

说明img和img1两张图片都是3通道,尺寸长宽分别是900 x 900和1080 x 1920

3.只提取灰度图片

如果读取图片的时候加上第二参数cv2.IMREAD_GRAYSCALE,或者0

就可以读取灰度图

输出结果如下

同时图片参数的输出也只有长宽两个参数

4.保存图片

利用cv2.imwrite()可以保存处理过的图片

cv2.imwrite('D:\\opencv\\picture\\catGray.jpg', img)
cv2.imwrite('D:\\opencv\\picture\\TOMGRAY.jpg', img1)

可以看到灰度图已经保存在指定的路径中

5.计算图片像素

利用print(img.size, img1.size)可以计算图片像素大小

可以看到输出结果为 810000和2073600,这和上面计算出的图片长宽数据是一致的

6.截取部分图像数据

cat = img[400:800, 100:800]

这里的尺寸,参数1是高度从400到800,参数2是宽度从100到800

7.截取部分图像数据

import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('D:\\opencv\\picture\\cat.jpg')  # opencv读取的格式是RGB
img1 = cv2.imread('D:\\opencv\\picture\\TOM.jpg', 0)
b, g, r = cv2.split(img)  # 分离图像的三个通道
print(b, g, r)
print(b.shape, g.shape, r.shape)  # 可以看到分离通道后的图尺寸还是相同的
img2 = cv2.merge((b, g, r))    # 处理完分离后的图像还可以合成回去
print(img2.shape)

这里可以看到b,g,三个通道分离后的数据是不一样的,分离后的图像尺寸不变

8.只保留某一通道

b g r三颜色通道分别对应0, 1, 2

如下述代码将绿色,蓝色两个通道过滤掉,只剩下红色通道

cur_img[:, :, 0] = 0
cur_img[:, :, 1] = 0

同类理获得其他通道

9.边界填充

边界填充有主要以下几种,详情见代码

import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('D:\\opencv\\picture\\cat.jpg')  # opencv读取的格式是RGB
img1 = cv2.imread('D:\\opencv\\picture\\TOM.jpg', 0)
b, g, r = cv2.split(img)
img2 = cv2.merge([r, g, b])
top_size, bottom_size, left_size, right_size = (300, 300, 300, 300)
replicate = cv2.copyMakeBorder(img2, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img2, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img2, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img2, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img2, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_CONSTANT, value=0)
plt.subplot(231), plt.imshow(img2, '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()

运行结果如下

BORDER_REPLICATE: 复制法,也就是复制最边缘像素。

BORDER_REFLECT: 反射法,对感兴趣的图像中的像素在两边进行复制例如: fedcba|abcdefgh|hgfedcb

BORDER_REFLECT 101: 反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba

BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg

BORDER_CONSTANT: 常量法,常数值填充,这里用的是0值填充,就是黑色外边框。

10.视频数据读取

这里解释一下while循环

while open:  # 如果if代码中的open的布尔值为True,就一直处理图像到视频结束
    ret, frame = vc.read()    
    if frame is None:    # 如果能读到视频中的图像,就一直读取下去
        break            # 如果读取不到视频中的图像了,则退出程序
    if ret:    # 简单写法,if ret == True     如果这一帧的图像存在
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)     # 将图像转换成灰度图
        cv2.imshow('result', gray)
        if cv2.waitKey(10) & 0xFF == 27:   # waiykey是视频的时间,0xFF == 27是键盘退出键,按下Esc键可以直接退出循环
            break

二. 形态学

1.腐蚀操作

<1>腐蚀操作原理

就像土壤侵蚀一样,这个操作会把前景物体的边界腐蚀掉。这是怎么做到的呢?卷积核沿着图像滑动,如果与卷积核对应的图像的所有像素值都是1,那么该区域的所有像素值就是1,否则为0。用于去除白噪声和断开两个连在一起的物体等。用到的函数是cv2.erode()

<2>案例

这里有一张图片,是一个"道"字,但是边缘有毛刺一样的东西

这里对这个"道"字进行腐蚀操作,可以看到毛刺已经去掉

代码分析

(1)erode()函数

erode()函数可以对输入图像用特定结构元素进行腐蚀操作,该结构元素确定腐蚀操作过程中的邻域的形状,各点像素值将被替换为对应邻域上的最小值

这里对主要参数进行解释

src:表示输入图像;

kernel:表示定义的卷积核

这里要是把卷积核整大一点,可以看到图像被腐蚀的更多

iterations:表示迭代腐蚀的次数,通俗的说就是腐蚀多少次。

这里要是把腐蚀的次数加大一点,可以看到文字更细了,腐蚀的更多了

2.膨胀操作

<1>膨胀操作原理

对二值化物体边界点进行扩充,将与物体接触的所有背景点合并到该物体中,使边界向外部扩张。如果两个物体间隔较近,会将两物体连通在一起。对填补图像分割后物体的空洞有用。

<2>案例

上述"道"字被腐蚀之后,可以利用膨胀操作,可以看到断连的部分已经连接起来了

3.开运算与闭运算

<1>概念

开运算:先腐蚀,再膨胀

闭运算:先膨胀,再腐蚀

<2>开运算案例

<3>闭运算案例

这里发现先进行膨胀,然后再腐蚀,毛刺更多了,是因为毛刺被膨胀加强了,然后再想腐蚀就麻烦了

开和闭主要影响图像边界,一个让凸出来的部分消失,一个让凹进去的部分填平

4.梯度运算

<1>概念

梯度 = 膨胀 - 腐蚀

梯度运算可以得出一个图像的轮廓信息

<2>案例

如下图案例所示,膨胀操作之后的图像减去腐蚀操作之后的图像,得到了图像中间的空心轮廓

5.礼帽与黑帽

<1>概念

礼帽 = 原始输入 - 开运算

黑帽 = 闭运算 - 原始输入

<2>礼帽案例

可以看到输出的图片只剩下了毛刺

<3>黑帽案例

可以看到输出的图片只剩下了边框

附注:这里总结几个报错

1.cv2.error: OpenCV(4.5.3)

初学第一个代码就报错了

cv2.error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-q3d_8t8e\opencv\modules\imgproc\src\color.

cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'

经过查询,发现是图片中出现了中文路径,这里把路径换成英文的就没事了

2.plt.imshow()不显示图片

用matplotlib库中的plt.imshow()不显示图片,但是程序运行正常

解决办法,在代码最后一行加plt.show(),如下图所示

3.plt.imshow()图片显示失真

如下左边图所示,图中的猫猫颜色已经失真了,代码如上面错误2中

这是因为cv2中图像通道是按照bgr排列的,而matplotlib是按照rgb排列的

因此要将颜色通道重新排列,可以看到右侧猫猫颜色已经正常了

b, g, r = cv2.split(img)
img2 = cv2.merge([r, g, b])

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值