OpenCV学习

OpenCV基础的图像操作

1.读取图像

cv2.imread(path,[读取方式])

参数:

  • path:要读取的图像路径

  • 读取方式的标志(彩色-默认,灰色等等),可以在读取图片时进行操作,例如将图片转化为灰度图像等

2.显示图像

cv2.imshow(name,image_name)

参数:

  • name:显示图像的窗口名称,以字符串类型表示
  • image_name:要加载的图像

注意:在调用显示图像的API后,要调用cv2.waitKey(0)给图像绘制留下时间,否则窗口会出现无响应情况,并且图像无法显示出来

3.保存图像

cv2.imwrite(path,image_name)

参数:

  • path:文件名,要保存在哪里
  • image_name:要保存的图像
import cv2

# 读取图像
im = cv2.imread('./my_images/1.png')

# 显示图像
cv2.imshow("img", im)

# 保存图像
# 将图像转化为灰度图像
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imwrite("./my_images/2.png", im)

cv2.waitKey(0)

绘制几何图形

1.绘制直线

cv2.line(img,start,end,color,thickness)

参数:

  • img:要绘制直线的图像
  • Start,end: 直线的起点和终点
  • color: 线条的颜色
  • Thickness: 线条宽度

2.绘制圆形

cv.circle(img,centerpoint, r, color, thickness)

参数:

  • img:要绘制圆形的图像
  • centerpoint, r: 圆心和半径
  • color: 线条的颜色
  • thickness: 线条宽度,为-1时生成闭合图案并填充颜色

3.绘制矩形

cv.rectangle(img,leftupper,rightdown,color,thickness)

参数:

  • img:要绘制矩形的图像
  • Leftupper, rightdown: 矩形的左上角和右下角坐标
  • color: 线条的颜色
  • Thickness: 线条宽度

4.向图像中添加文字

cv.putText(img,text,org, fontFace, Fontscale ,color,thickness,cv2.LINE_AA)

参数:

  • img: 图像

  • text:要写入的文本数据

  • org:文本的放置位置

  • fontFace:字体样式

  • Fontscale :字体大小

  • color:字体颜色

  • thickness字体线条宽度

  • cv2.LINE_AA

    最后一个参数 cv2.LINE_AA 表示使用反走样(Anti-Aliasing)技术来绘制文本边框。不填该参数时,默认使用的是cv2.LINE_8

import cv2

# 绘制直线
im = cv2.imread("./my_images/1.png")
# print(im.shape)
cv2.line(im, (100, 100), (900, 100), (0, 0, 255), 2)

# 绘制圆形
cv2.circle(im, (450, 500), 100, (255, 0, 0), 1)

# 绘制矩形
cv2.rectangle(im, (300, 300), (600, 600), (0, 255, 0), 2)

# 向图像中添加文字
cv2.putText(im, "yahu!!!", (100, 150), cv2.FONT_ITALIC, 2, (255, 0, 0))

# 修改图像中的某一个像素点
im[50, 50] = [0, 0, 255]

cv2.imshow("img", im)
cv2.waitKey(0)

摄像头操作

注意:在使用完摄像头之后要记住释放资源关闭摄像头

import cv2

"""
cap = cv2.VideoCapture(path)# path视频文件,当参数设置为0时,表示从默认摄像头获取视频
ret, frame = cap.read()# 返回一个布尔值和一帧图像
"""
cap = cv2.VideoCapture(0)

while True:
    # 获取一帧图像
    ret, frame = cap.read()
    if ret is False or cv2.waitKey(1) == ord('q'):
        break
    # 对图像进行灰度化处理
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 采用高斯加权求和进行自适应二值化
    frame = cv2.adaptiveThreshold(frame, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 5)
    cv2.imshow('frame', frame)

# 释放摄像头资源并关闭所有窗口
cap.release()
cv2.destroyAllWindows()

计算机眼中的图像

1.像素

像素是图像的基本单元,每个像素存储着图像的颜色、亮度和其他特征。一系列像素组合到一起就形成了完整的图像,在计算机中,图像以像素的形式存在并采用二进制格式进行存储。根据图像的颜色不同,每个像素可以用不同的二进制数表示。

日常生活中常见的图像是RGB三原色图。RGB图上的每个点都是由红(R)、绿(G)、蓝(B)三个颜色按照一定比例混合而成的,几乎所有颜色都可以通过这三种颜色按照不同比例调配而成。在计算机中,RGB三种颜色被称为RGB三通道,根据这三个通道存储的像素值,来对应不同的颜色。

2.图像

计算机采用0/1编码的系统,数字图像也是利用0/1来记录信息,我们平常接触的图像都是8位数图像,包含0~255灰度,其中0,代表最黑,1,表示最白。

常用的图像:

  • 二值图像:图像中的颜色只有两种值可取
  • 灰度图:单通道图
  • 彩色图:R,G,B三通道图

图像灰度化方法

1. 最大值法

对于彩色图像的每个像素,它会从R、G、B三个通道的值中选出最大的一个,并将其作为灰度图像中对应位置的像素值。

2. 平均值法

对于彩色图像的每个像素,它会将R、G、B三个通道的像素值全部加起来,然后再除以三,得到的平均值就是灰度图像中对应位置的像素值。

3. 加权均值法

对于彩色图像的每个像素,它会按照一定的权重去乘以每个通道的像素值,并将其相加,得到最后的值就是灰度图像中对应位置的像素值。

import cv2
import numpy as np

# 最大值法
im = cv2.imread("./my_images/1.png")
im_gray = np.zeros((im.shape[0], im.shape[1]), dtype=np.uint8)

for row in range(im.shape[0]):
    for col in range(im.shape[1]):
        im_gray[row, col] = max(im[row, col][0], im[row, col][1], im[row, col][2])

cv2.imshow("im_gray", im_gray)
cv2.waitKey(0)

# 平均值法
im = cv2.imread("./my_images/1.png")
im_gray = np.zeros((im.shape[0], im.shape[1]), dtype=np.uint8)

for row in range(im.shape[0]):
    for col in range(im.shape[1]):
        im_gray[row, col] = (int(im[row, col][0]) + int(im[row, col][1]) + int(im[row, col][2]))/3

cv2.imshow("im_gray", im_gray)
cv2.waitKey(0)

# 加权均值法
im = cv2.imread("./my_images/1.png")
im_gray = np.zeros((im.shape[0], im.shape[1]), dtype=np.uint8)

for row in range(im.shape[0]):
    for col in range(im.shape[1]):
        im_gray[row, col] = int(im[row, col][0]*0.114) + int(im[row, col][1]*0.587) + int(im[row, col][2]*0.299)

cv2.imshow("im_gray", im_gray)
cv2.waitKey(0)

二值化方法

1. 阈值法(THRESH_BINARY)

阈值法就是通过设置一个阈值,将灰度图中的每一个像素值与该阈值进行比较,小于等于阈值的像素就被设置为0(黑),大于阈值的像素就被设置为maxval。

2. 反阈值法(THRESH_BINARY_INV)

顾名思义,就是与阈值法相反。反阈值法是当灰度图的像素值大于阈值时,该像素值将会变成0(黑),当灰度图的像素值小于等于阈值时,该像素值将会变成maxval。

3. 截断阈值法(THRESH_TRUNC)

截断阈值法,指将灰度图中的所有像素与阈值进行比较,像素值大于阈值的部分将会被修改为阈值,小于等于阈值的部分不变。

4. 低阈值零处理(THRESH_TOZERO)

低阈值零处理,像素值小于等于阈值的部分被置为0,大于阈值的部分不变。

5. 超阈值零处理(THRESH_TOZERO_INV)

超阈值零处理将灰度图中的每个像素与阈值进行比较,像素值大于阈值的部分置为0,像素值小于等于阈值的部分不变。

import cv2

# 读入图片转化为灰度图像
im = cv2.imread("./my_images/1.png", cv2.IMREAD_GRAYSCALE)

# 阈值法,阈值为127,大于阈值设置为255,小于设置为0
_, im = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)
cv2.imshow("im", im)
cv2.waitKey(0)

# 反阈值法,阈值为127,大于阈值设置为0,小于设置为255
_, im = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY_INV)
cv2.imshow("im", im)
cv2.waitKey(0)

# 截断阈值法,大于阈值的部分将会被修改为阈值,小于等于阈值的部分不变
_, im = cv2.threshold(im, 127, 255, cv2.THRESH_TRUNC)
cv2.imshow("im", im)
cv2.waitKey(0)

# 低阈值零处理,像素值小于等于阈值的部分被置为0,大于阈值的部分不变
_, im = cv2.threshold(im, 127, 255, cv2.THRESH_TOZERO)
cv2.imshow("im", im)
cv2.waitKey(0)

# 超阈值零处理,像素值大于等于阈值的部分被置为0,小于阈值的部分不变
_, im = cv2.threshold(im, 127, 255, cv2.THRESH_TOZERO_INV)
cv2.imshow("im", im)
cv2.waitKey(0)

6.OTSU阈值法(后续补充)

自适应二值化方法

与二值化算法相比,自适应二值化更加适合用在明暗分布不均的图片,图片上的每一小部分都要使用不同的阈值进行二值化处理

cv2.adaptiveThreshold(image_np_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 7, 10)

参数:

  • maxval:最大阈值,一般为255
  • adaptiveMethod:小区域阈值的计算方式:
  • ADAPTIVE_THRESH_MEAN_C:小区域内取均值
  • ADAPTIVE_THRESH_GAUSSIAN_C:小区域内加权求和,权重是个高斯核
  • thresholdType:二值化方法,只能使用THRESH_BINARY、THRESH_BINARY_INV,也就是阈值法和反阈值法
  • blockSize:卷积核,选取的小区域的面积,如7就是7*7的小块。
  • c:最终阈值等于小区域计算出的阈值再减去此值

1.取均值

在这里插入图片描述

注意:如果处于边缘地区就会对边界进行填充,填充值就是边界的像素点。我们所用到的不断滑动的小区域被称之为核,比如3*3的小区域叫做3*3的核,并且核的大小都是奇数个,也就是3*3、5*5、7*7等。

2.加权求和

对小区域内的像素进行加权求和得到新的阈值,其权重值来自于高斯分布。

高斯分布,通过概率密度函数来定义高斯分布,一维高斯概率分布函数为:
p ( y ) = 1 σ 2 π e − ( y − μ ) 2 2 σ 2 p(y)={\frac{1}{\sigma{\sqrt{2\pi}}}}e^{{\frac{-(y-\mu)^{2}}{2\sigma^{2}}}} p(y)=σ2π 1e2σ2(yμ)2
此时我们拓展到二维图像,一般情况下我们使x轴和y轴的相等并且,此时我们可以得到二维高斯函数的表达式为:
g ( x , y ) = 1 2 π σ 2 e − ( x 2 + y 2 ) 2 σ 2 g(x,y)=\frac{1}{2\pi\sigma ^{2}}e^{-\frac{(x^{2}+y^{2})}{2\sigma^{2}}} g(x,y)=2πσ21e2σ2(x2+y2)
要产生一个3*3的高斯权重核,以核的中心位置为坐标原点进行取样,其周围的坐标如下图所示(x轴水平向右,y轴竖直向上)

在这里插入图片描述

kernel尺寸核值
1[1]
3[0.25, 0.5, 0.25]
5[0.0625, 0.25, 0.375, 0.25, 0.0625]
7[0.03125, 0.109375, 0.21875, 0.28125, 0.21875, 0.109375, 0.03125]

当核的大小为3x3时,我们使用kernel尺寸为3的核值乘以它对应的矩阵的转置得到一个方阵,最终的到kernel高斯核,再相应的对应到每个像素点进行加权求和即可得到中心点的阈值

注:

  • 在opencv里,当kernel(小区域)的尺寸为1、3、5、7并且用户没有设置sigma的时候(sigma <= 0),核值就会取固定的系数,这是一种默认的值是高斯函数的近似。

  • 当kernels尺寸超过7的时候,如果sigma设置合法(用户设置了sigma),则按照高斯公式计算.当sigma不合法(用户没有设置sigma),则按照如下公式计算sigma的值:

σ = 0.3 ∗ ( ( k s i z e − 1 ) ∗ 0.5 − 1 ) + 0.8 \sigma=0.3*\big((k s i z e-1)*0.5-1\big)+0.8 σ=0.3((ksize1)0.51)+0.8

import cv2

# 读入图片转化为灰度图像
im = cv2.imread("./my_images/1.png", cv2.IMREAD_GRAYSCALE)
cv2.imshow("im", im)
cv2.waitKey(0)

# 取均值法
im = cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 5)
cv2.imshow("im", im)
cv2.waitKey(0)

# 加权求和法
im = cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 5)
cv2.imshow("im", im)
cv2.waitKey(0)

读入图片转化为灰度图像

im = cv2.imread(“./my_images/1.png”, cv2.IMREAD_GRAYSCALE)
cv2.imshow(“im”, im)
cv2.waitKey(0)

取均值法

im = cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 5)
cv2.imshow(“im”, im)
cv2.waitKey(0)

加权求和法

im = cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 5)
cv2.imshow(“im”, im)
cv2.waitKey(0)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值