OpenCV基础02_图像预处理

图像预处理

在计算机视觉和图像处理领域,图像预处理是一个重要的步骤,它能够提高后续处理(如特征提取、目标检测等)的准确性和效率。

OpenCV 提供了许多图像预处理的函数和方法,一些常见的图像预处理操作:

  1. 图像色彩空间转换

  2. 图像大小调整

  3. 图像仿射变换

  4. 图像翻转

  5. 图像裁剪

  6. 图像二值化处理

  7. 图像去噪

  8. 边缘检测

  9. 图像平滑处理

  10. 图像形态学

一、图像翻转

cv2.flip 是 OpenCV 库中的一个函数,用于翻转图像。翻转可以是水平翻转、垂直翻转或同时水平和垂直翻转。这个函数接受两个参数:要翻转的图像和一个指定翻转类型的标志。

import cv2

img = cv2.imread('../images/car.png')

"""
图像翻转
  cv2.flip(src, flipCode[, dst])
    - src:输入图像,可以是任意类型和深度的多通道图像。
    - flipCode:指定翻转类型的整数标志:
      - `0`:沿 X 轴翻转(垂直翻转)
      - `1`:沿 Y 轴翻转(水平翻转)
      - `-1`:沿 X 轴和 Y 轴翻转(同时水平和垂直翻转)
    - dst:可选参数,输出图像。如果未提供,输出图像将与输入图像具有相同的尺寸和类型。
"""
# 垂直翻转 0
# f_img = cv2.flip(img, 0)
# 水平翻转 1
# f_img = cv2.flip(img, 1)
# 同时水平喝垂直翻转 -1
f_img = cv2.flip(img, -1)

cv2.imshow('old', img)
cv2.imshow('new', f_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

二、图像仿射变换

仿射变换(Affine Transformation)是一种线性变换,它保持了点之间的相对距离不变,即平行线在变换后仍然保持平行。在图像处理中,仿射变换常用于旋转、缩放、平移和剪切等操作。

1、图像旋转

旋转操作可以将图像绕着某个点旋转一定的角度。

import cv2

img = cv2.imread('../images/car.png')

"""
图像翻转
  cv2.flip(src, flipCode[, dst])
    - src:输入图像,可以是任意类型和深度的多通道图像。
    - flipCode:指定翻转类型的整数标志:
      - `0`:沿 X 轴翻转(垂直翻转)
      - `1`:沿 Y 轴翻转(水平翻转)
      - `-1`:沿 X 轴和 Y 轴翻转(同时水平和垂直翻转)
    - dst:可选参数,输出图像。如果未提供,输出图像将与输入图像具有相同的尺寸和类型。
"""
# 垂直翻转 0
# f_img = cv2.flip(img, 0)
# 水平翻转 1
# f_img = cv2.flip(img, 1)
# 同时水平喝垂直翻转 -1
f_img = cv2.flip(img, -1)

cv2.imshow('old', img)
cv2.imshow('new', f_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

2、图像平移

平移操作可以将图像中的每个点沿着某个方向移动一定的距离。

import cv2
import numpy as np

img = cv2.imread('../images/car.png')
"""
图像平移
  将图像中的每个点沿着某个方向移动一定的距离
"""
# 获取图像像素
(h, w) = img.shape[:2]

# 定义 平移水平和垂直移动的距离
# tx 和 ty 分别表示在x轴和y轴方向上的平移距离
ty = 50
tx = 100

# 创建平移矩阵
M = np.float32([[1, 0, tx], [0, 1, ty]])

# 应用平移变换
W_img = cv2.warpAffine(img, M, (w, h))

cv2.imshow('m', W_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

3、图像缩放

缩放操作可以改变图像的大小。

import cv2
import numpy as np

img = cv2.imread('../images/car.png')
(h, w) = img.shape[:2]

# 定义缩放参数
# 大于1 放大  小于1 缩小
# sx 和 sy 分别表示在x轴和y轴方向上的缩放因子
sx = 0.5
sy = 0.5
M = np.float32([[sx, 0, 0], [0, sy, 0]])

# 应用缩放变换
s_img = cv2.warpAffine(img, M, ((int(w*sx)), int(h*sy)))

# 显示结果
cv2.imshow('Scaled Image', s_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

4、图像剪切

剪切操作可以改变图像的形状,使其在某个方向上倾斜。

import cv2
import numpy as np

img = cv2.imread('../images/car.png')
rows, cols = img.shape[:2]

"""
图像剪切
  改变图像的形状,使其在某个方向上倾斜
"""

# 定义剪切因子
shx, shy = 0.1, 0.5
M = np.float32([[1, shx, 0], [shy, 1, 0]])

# 剪切图片
s_img = cv2.warpAffine(img, M, (cols, rows))

# 显示结果
cv2.imshow('Sheared Image', s_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

三、图像色彩空间转换

OpenCV中的色彩空间转换是将图像从一种颜色表示形式转换为另一种颜色表示形式的过程。常见的颜色空间包括RGB、HSV、YUV等。

作用

  1. 方便图像处理:在不同的颜色空间中,对应的通道代表了不同的属性,例如在RGB空间中,红、绿、蓝三个通道分别代表了颜色的强度,而在 HSV 空间中,H (色相)代表了颜色的种类,S (饱和度)代表了颜色的深浅,V (亮度)代表了颜色的明暗。因此,对于不同的处理需求,选择不同的颜色空间进行处理可以更加方便。

  2. 提高图像处理效果:在某些情况下,使用某些特定的颜色空间可以提高图像处理的效果。例如,在HSV空间中,可以通过调整 S (饱和度)和 V (亮度)来提高图像的对比度并去除噪点。

  3. 节省计算资源:在某些情况下,使用特定的颜色空间可以帮助我们节省计算资源。例如,在RGB空间中,每个像素需要3个通道来表示,而在灰度空间中,每个像素只需要一个通道就可以表示。因此,如果只需要处理亮度信息而不需要颜色信息时,将图像转换为灰度空间可以节省计算资源。

cv2.cvtColor()是OpenCV中的一个函数,用于图像颜色空间的转换。它可以将一个图像从一个颜色空间转换为另一个颜色空间,比如从RGB到灰度图像的转换,或者从BGR到HSV的转换等。

cv2.cvtColor(src, code)

 参数

  • src:输入图像,可以是一个NumPy数组或者一个OpenCV的Mat对象。

  • code:指定转换的类型,可以使用预定义的转换代码,例如cv2.COLOR_BGR2GRAY表示从BGR到灰度图像的转换。

1、RGB转灰度图像

RGB 转 Gray(灰度),将彩色图像转换为灰度图像,可以减少数据量并简化算法。

import cv2

img = cv2.imread('../images/car.png')
"""
图像色彩空间转换
  opencv 默认的图像格式为BGR
"""

# COLOR_BGR2GRAY BGR图像->灰度图像
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

2、RGB转HSV

RGB 转 HSV,HSV(Hue, Saturation, Value)色彩空间在颜色分割和颜色识别中非常有用。

# cv2.COLOR_BGR2HSV BGR图像->HSV图像
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

四、图像二值化处理

cv2.threshold 是 OpenCV 中用于图像二值化的函数。它通过设置阈值将图像分为前景和背景,常用于图像处理和分析。

cv2.threshold 将灰度图像转换为二值图像,根据指定的阈值将像素值分为两类:高于阈值的像素设为一个值(通常是255),低于阈值的像素设为另一个值(通常是0)。

retval, dst = cv2.threshold(src, thresh, maxval, type)

 参数

  1. src: 输入的灰度图像。

  2. thresh: 阈值,决定分割的界限。

  3. maxval: 当像素值超过阈值时,赋予的最大值(通常为255)。

  4. type

    : 阈值类型,常用的有:

    • cv2.THRESH_BINARY: 超过阈值的像素设为最大值,其余设为0。

    • cv2.THRESH_BINARY_INV: 超过阈值的像素设为0,其余设为最大值。

    • cv2.THRESH_TRUNC: 超过阈值的像素设为阈值,其余不变。

    • cv2.THRESH_TOZERO: 超过阈值的像素不变,其余设为0。

    • cv2.THRESH_TOZERO_INV: 超过阈值的像素设为0,其余不变。

返回值

  • retval: 实际使用的阈值(可能与输入值不同)。

  • dst: 输出的二值图像。

import cv2

"""
cv2.threshold
  将灰度图像转换为二值图像
  它通过设置阈值将图像分为前景和背景,常用于图像处理和分析。
  根据指定的阈值将像素值分为两类:
    高于阈值的像素设为一个值(通常是255)
    低于阈值的像素设为另一个值(通常是0)
"""

# 读取图像并转换为灰度图
img = cv2.imread('../images/car.png')
g_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#  二值化处理
# rs 实际应用阈值  t_img 转换后的图像
rs, t_img = cv2.threshold(g_img, 100, 500, cv2.THRESH_BINARY)

# 显示结果
cv2.imshow('原图', img)
cv2.imshow('二值图像', t_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

五、图像掩模

通常用于创建掩模,以便从图像中提取特定颜色的区域。

cv2.inRange(src, lowerb, upperb)

 

import cv2
import numpy as np

"""
cv2.inRange(src, lowerb, upperb)
  通常用于创建掩模,以便从图像中提取特定颜色的区域
  参数
    - src: 输入的图像,可以是彩色图像或灰度图像。
    - lowerb: 颜色范围的下界(数组或元组),指定了要提取的颜色的最小值。
    - upperb: 颜色范围的上界(数组或元组),指定了要提取的颜色的最大值。
  返回值
    返回一个二值图像:
      白色部分表示在指定颜色范围内的区域;
      黑色部分表示不在范围内的区域。
"""

img = cv2.imread('../images/car3.png')
# 把图像转换为HSV空间
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 获取蓝色所在的HSV范围
lowerb = np.array([100, 100, 50])
upperb = np.array([140, 255, 255])
# 创建掩模
mask = cv2.inRange(hsv_img, lowerb, upperb)

cv2.imshow('mask', mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

六、图像检测轮廓

cv2.findContours 函数可以在二值图像中找到轮廓,并返回轮廓的点集。轮廓可以用来表示物体的边界,常用于物体检测、分割和形状分析。

contours, hierarchy = cv2.findContours(image, mode, method)

参数

  1. image: 输入的二值图像。通常在调用该函数之前需要将图像转换为灰度图像并进行二值化处理(如使用 cv2.thresholdcv2.Canny)。

  2. mode

    : 轮廓检索模式:

    • cv2.RETR_EXTERNAL: 只检索外部轮廓。

    • cv2.RETR_LIST: 检索所有轮廓,并将其放入列表中。

    • cv2.RETR_TREE: 检索所有轮廓,并建立层级关系。

  3. method

    : 轮廓逼近方法:

    • cv2.CHAIN_APPROX_SIMPLE: 压缩轮廓,仅保留端点。

    • cv2.CHAIN_APPROX_NONE: 保留所有轮廓点。

返回值

  • contours: 一个 Python 列表,其中每个元素是一个轮廓(即一组点),轮廓的点以 NumPy 数组的形式存储。

  • hierarchy: 轮廓的层级信息,包含轮廓之间的关系。

import cv2
import numpy as np

"""
cv2.findContours
  可以在二值图像中找到轮廓,并返回轮廓的点集。
  轮廓可以用来表示物体的边界,常用于物体检测、分割和形状分析。
  
  contours, hierarchy = cv2.findContours(image, mode, method)
    参数
      1. image: 输入的二值图像。
      通常在调用该函数之前需要将图像转换为灰度图像并进行二值化处理
      (如使用 `cv2.threshold` 或 `cv2.Canny`)。
      2. mode: 轮廓检索模式:
        - cv2.RETR_EXTERNAL: 只检索外部轮廓。
        - cv2.RETR_LIST: 检索所有轮廓,并将其放入列表中。
        - cv2.RETR_TREE: 检索所有轮廓,并建立层级关系。
      3. method: 轮廓逼近方法:
        - cv2.CHAIN_APPROX_SIMPLE: 压缩轮廓,仅保留端点。
        - cv2.CHAIN_APPROX_NONE: 保留所有轮廓点。
        
    返回值
      - contours: 一个 Python 列表,其中每个元素是一个轮廓(即一组点),轮廓的点以 NumPy 数组的形式存储。
      - hierarchy: 轮廓的层级信息,包含轮廓之间的关系。
"""

img = cv2.imread('../images/car3.png')
# 把图像转换为HSV空间
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 获取蓝色所在的HSV范围
lowerb = np.array([100, 100, 50])
upperb = np.array([140, 255, 255])
# 创建掩模
mask = cv2.inRange(hsv_img, lowerb, upperb)

# 二值化处理
ret, b_img = cv2.threshold(mask, 127, 255, cv2.THRESH_BINARY)

# 检测轮廓
# cv2.RETR_EXTERNAL: 只检索外部轮廓 CHAIN_APPROX_SIMPLE: 压缩轮廓,仅保留端点
contours, hierarchy = cv2.findContours(b_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# cv2.RETR_LIST: 检索所有轮廓,并将其放入列表中
# contours, hierarchy = cv2.findContours(b_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

# 灰度图像转换为彩色图像 COLOR_GRAY2BGR
bgr_img = cv2.cvtColor(b_img, cv2.COLOR_GRAY2BGR)
# 绘制轮廓
output_img = cv2.drawContours(bgr_img, contours, -1, (0, 255, 0), 1)
# # 获取绘制轮廓的边界框
# for c in contours:
#     x, y, w, h = cv2.boundingRect(c)
#     print(x, y, w, h)

# 边界框 405 299 225 73
cv2.rectangle(output_img, (405, 299), (405+225, 299+73), (0, 0, 255), 2)
# 显示结果
cv2.imshow('output', output_img)
cv2.waitKey(0)
cv2.destroyAllWindows()




练习:对车牌的分隔提取

import cv2
import numpy as np

img = cv2.imread('../images/car3.png')

"""
创建掩模->方便缩小识别范围->限定在车牌
"""
# 把图像转换为HSV空间
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
"""
例图中的车牌背景色都为蓝色->获取蓝色所在的HSV范围
"""
lowerb = np.array([100, 100, 50])
upperb = np.array([140, 255, 255])
# 创建掩模
mask = cv2.inRange(hsv_img, lowerb, upperb)

# 二值化处理
ret, b_img = cv2.threshold(mask, 125, 255, cv2.THRESH_BINARY)

# 获取图片轮廓
contours, hierarchy = cv2.findContours(b_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
"""
根据找到的车牌大小估计识别范围
"""
for contour in contours:
    x, y, w, h = cv2.boundingRect(contour)
    # print(x, y, w, h)
    # 绘制矩形  326 170 168 54
    if w > 150 and h > 45:
        cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
        # 截取车牌号
        end_img = img[y:y+h, x:x+w]

# 显示结果
cv2.imshow('old', img)
cv2.imshow('output', end_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/906785.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ctf文件上传题小总结与记录

解题思路:先看中间件,文件上传点(字典扫描,会员中心),绕过/验证(黑名单,白名单),解析漏洞,cms,编辑器,最新cve 文件上传漏…

安全成为大模型的核心;大模型安全的途径:大模型对齐

目录 安全成为大模型的核心 大模型安全的途径:大模型对齐 人类反馈强化学习(RLHF) 直接偏好优化(DPO) 安全成为大模型的核心 大模型安全的途径:大模型对齐 大模型对齐技术(Alignment Techniques for Large Language Models)是确保大规模语言模型(例如GPT-4)的输…

基于知识引导提示的因果概念提取(论文复现)

基于知识引导提示的因果概念提取(论文复现) 本文所涉及所有资源均在传知代码平台可获取 文章目录 基于知识引导提示的因果概念提取(论文复现)论文概述论文方法提示构造器获取典型概念集聚类典型概念构建训练数据训练主题分类器概念提取器输入构造指针网络置信度评分训练损失…

Rust的enum枚举的强大用法

在Rust中,enum(枚举)是一种非常强大的类型,它可以包含多个变体(variants),每个变体可以是不同的类型,包括复杂类型。这使得enum在Rust中不仅用于表示简单的状态或选项集合&#xff0…

vue常用的修饰符有哪些

1、修饰符是什么 在Vue 中,修饰符处理了许多 DOM 事件的细节,让我们不再需要花大量的时间去处理这些烦恼的事情,而能有更多的精力专注于程序的逻辑处理 vue中修饰符分为以下五种 汇总修饰符说明表单lazy光标离开标签的时候,才会…

【创建型】单例模式

单例模式使用的场景:需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等) 1. 饿汉式(静态常量&#xf…

如何在Linux命令行中使用GhatGPT

2、验明正身,证明我的所在地是国内 3、第一次提问 4、第二次提问 5、问他一首古诗 6、话不多说,现在来展示他的安装过程 7、输入GitHub的网址 https://github.com/aandrew-me/tgpt 8、详情页向下翻 9、到终端输入 下列命令,等待安装&#x…

《机器人SLAM导航核心技术与实战》第1季:第10章_其他SLAM系统

视频讲解 【第1季】10.第10章_其他SLAM系统-视频讲解 【第1季】10.1.第10章_其他SLAM系统_RTABMAP算法 【第1季】10.2.第10章_其他SLAM系统_VINS算法 【第1季】10.3.第10章_其他SLAM系统_机器学习与SLAM 第1季:第10章_其他SLAM系统 先 导 课 第 1 季 &#xff…

比较36个结构的迭代次数

(A,B)---6*30*2---(0,1)(1,0) 让A是结构1,让B全是0。收敛误差为7e-4,收敛199次取迭代次数平均值,得到28080.98 做一个同样的网络(A,B)---6*30*2---(0,1)(1,0),让A分是结构1-12,B全是0,用结构1的收敛权重做…

8. 数据结构——邻接表、邻接矩阵的基本操作

一、邻接表 1. 内容 2. 实现代码(直接可以复制使用) //邻接表的相关操作 #include<bits/stdc.h> #define MVnum 100 #define OK 1 #define ERROR -1 using namespace std;typedef int Status; typedef char VerTexType; //假设顶点的数据类型为char typedef int ArcT…

Kafka 基础入门

文章内容是学习过程中的知识总结&#xff0c;如有纰漏&#xff0c;欢迎指正 文章目录 前言 1. 核心概念 1.1 Producer 1.2 broker 1.3 consumer 1.4 zookeeper 1.5 controller 1.6 Cluster 2. 逻辑组件 2.1 Topic 2.2 Partition 2.3 Replication 2.4 leader & follower 3. …

qt QDialog详解

1、概述 QDialog是Qt框架中用于创建对话框的类&#xff0c;它继承自QWidget。QDialog提供了一个模态或非模态的对话框&#xff0c;用于与用户进行交互。模态对话框会阻塞其他窗口的输入&#xff0c;直到用户关闭该对话框&#xff1b;而非模态对话框则允许用户同时与多个窗口进…

从0开始学PHP面向对象内容之(类,对象,构造/析构函数)

上期我们讲了面向对象的一些基本信息&#xff0c;这期让我们详细的了解一下 一、面向对象—类 1、PHP类的定义语法&#xff1a; <?php class className {var $var1;var $var2 "constant string";function classfunc ($arg1, $arg2) {[..]}[..] } ?>2、解…

双向链表及如何使用GLib的GList实现双向链表

双向链表是一种比单向链表更为灵活的数据结构&#xff0c;与单向链表相比可以有更多的应用场景&#xff0c;本文讨论双向链表的基本概念及实现方法&#xff0c;并着重介绍使用GLib的GList实现单向链表的方法及步骤&#xff0c;本文给出了多个实际范例源代码&#xff0c;旨在帮助…

一键搞定表格文件管理与转换,轻松将XLS格式的表格文件转换为TXT格式的文本文档,办公软件是提高工作效率的方法

在办公的海洋里&#xff0c;表格文件如同繁星点点&#xff0c;而XLS格式更是其中的璀璨明珠。但有时候&#xff0c;我们需要将这些明珠的光芒以另一种形式展现——比如&#xff0c;转换成TXT格式的文本文档。这时&#xff0c;首助编辑高手软件就像一位魔法师&#xff0c;轻轻一…

初始Docker

概述&#xff1a; 容器&#xff0c;作为云原生技术的重要组成部分&#xff0c;与虚拟机一样&#xff0c;均属于虚拟化技术的范畴。然而&#xff0c;容器技术以其独特的优势&#xff0c;在虚拟化领域中脱颖而出。与虚拟机不同&#xff0c;容器能够摆脱操作系统的束缚&#xff0…

TikTok如何用邮箱注册?用哪种邮箱比较好?

要在TikTok上创建一个账号&#xff0c;首先需要进行注册&#xff0c;这是一个简单但至关重要的步骤。在本篇文章中&#xff0c;我们将详细介绍如何用邮箱注册TikTok的整个过程&#xff0c;包括每个步骤的细节和注意事项。此外&#xff0c;我们还将讨论选择哪种邮箱比较好&#…

输电线路绝缘子缺陷分割系统:轻松训练模式

输电线路绝缘子缺陷分割系统源码&#xff06;数据集分享 [yolov8-seg&#xff06;yolov8-seg-C2f-MSBlock等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Global Al …

flink 自定义kudu connector中使用Metrics计数平均吞吐量,并推送到自定义kafkaReporter

文章目录 前言1. Registering metrics2. Metrics 的类型2.1 counter2.2 Gauge2.3 Histogram2.4 meter 3. 指标划分3.1 指标所属的范围3.2 默认所属 4. 自定义kudu connector中使用Metrics4.1 sink算子继承RichFunction4.2 注册指标4.3 计数逻辑4.4 自定义Reporter&#xff0c;推…

Calling short variants with GATK4

计算生物学实验5: Calling short variants with GATK4 1. 实验目的 本实验目的是利用 GATK4 工具准确高效地检测出基因组中的短变异。通过该工具对样本基因组进行分析&#xff0c;旨在发现单核苷酸变异&#xff08;SNV&#xff09;和小的插入缺失&#xff08;Indel&#xff0…