嵌入式人工智能应用-第三章 opencv操作 5 二值化、图像缩放

嵌入式人工智能应用

嵌入式人工智能应用-第三章 opencv操作 5 二值化

  • 嵌入式人工智能应用
  • [1 二值化](#1 二值化)
    • [1.1 概念介绍](#1.1 概念介绍)
    • [1.2 函数介绍](#1.2 函数介绍)
    • [1.2 基本应用](#1.2 基本应用)
    • [1.3 参考案例](#1.3 参考案例)
  • [2 图像缩放](#2 图像缩放)
    • [2.1 基本概念](#2.1 基本概念)
    • [2.2 函数介绍](#2.2 函数介绍)
    • [2.3 基本参考代码](#2.3 基本参考代码)
    • [2.4 pyrUp 和 pyrDown 函数](#2.4 pyrUp 和 pyrDown 函数)
    • [2.5 函数介绍](#2.5 函数介绍)
    • [2.6 参考代码](#2.6 参考代码)
    • [2.7 总结](#2.7 总结)

1 二值化

1.1 概念介绍

二值化是图像分割的一种重要方法,图像的二值化就是将图像的表示方法缩减成两种状态,要么是 0,要么是 1,对于肉眼看到的就是非黑即白。一幅彩色图像,比如是 RGB888 的,则有 R/G/B 三个通道,每个通道的位深都是 8,所以 R、G、B 都有 0 到 255 的变化空间,表现出来的就是 256 种颜色。三个通道柔和在一起表示一个像素点,就有 224 种颜色。灰度图像是将 RGB 三个通道缩减到一个通道,于是他的变化空间就是 0 到 255,也就是 256 种颜色。二值图像就是将变化范围缩减到 0 到 1,也就是 2 种颜色。

图像处理中非常重要的一步,尤其在图像分析、物体识别、边缘检测中经常用到。

1.2 函数介绍

cv::threshold 是 OpenCV 中用于图像二值化的一个非常重要的函数。它可以将图像中的像素值根据给定的阈值进行分类,并将结果映射为两个值(通常是黑或白)。这个函数不仅支持简单的阈值处理,还支持一些先进的二值化算法。

cpp 复制代码
cv::threshold(
    const cv::Mat& src,        // 输入图像
    cv::Mat& dst,              // 输出图像
    double thresh,             // 阈值(如果是 Otsu 等方法,这个值会被自动计算)
    double maxValue,           // 设定的最大值,通常是255
    int thresholdType          // 阈值类型(例如 THRESH_BINARY, THRESH_OTSU 等)
);

参数解释:

src:输入图像,必须是灰度图(CV_8UC1)。

dst:输出图像,和输入图像大小相同,存储二值化后的结果。

thresh:阈值,决定哪些像素变成白色,哪些变成黑色。

maxValue:最大值,一般设为 255,表示白色。

thresholdType:阈值类型(有多种选择,下面会详细介绍)

cpp 复制代码
阈值类型	说明
THRESH_BINARY	如果像素值大于阈值,输出最大值(如 255),否则输出 0(黑色)。
THRESH_BINARY_INV	与 THRESH_BINARY 相反,像素值大于阈值的变为 0(黑),小于阈值的变为最大值(白)。
THRESH_TRUNC	如果像素值大于阈值,则将该像素值设置为阈值;否则不改变。
THRESH_TOZERO	如果像素值大于阈值,保留原值;否则将其设为 0(黑色)。
THRESH_TOZERO_INV	与 THRESH_TOZERO 相反,像素值小于阈值时保留原值,其他设置为 0(黑)。
THRESH_OTSU	自适应阈值选择方法。该方法通过最大化类间方差来选择最佳的阈值(无需手动设置阈值)。
THRESH_TRIANGLE	基于最大类间方差的阈值选择方法,类似 Otsu,但一般使用自适应的三角形方法。

1.2 基本应用

cpp 复制代码
cv::Mat grayImage = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat binaryImage;
cv::threshold(grayImage, binaryImage, 128, 255, cv::THRESH_BINARY);
// Otsu 二值化
cv::Mat otsuImage;
cv::threshold(grayImage, otsuImage, 0, maxValue, cv::THRESH_BINARY | cv::THRESH_OTSU);

1.3 参考案例

代码将一幅灰度图像进行二值化,然后显示出来。使用 OpenCV 提供的 Mat 定义两个变量,用于存储原始图像和二值化后的图像,OpenCV 提供的 imread 方法可以直接读取灰度图像,第二个参数 flag 默认是1,设置成 0 即可读取灰度图像。使用 OpenCV 提供的 threshold 方法进行二值化处理,处理结果存放在第二个参数 result 中。

c 复制代码
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
using namespace std;
int main(int argc,char* argv[])
{
 Mat img;
 Mat result;
 img = imread("cyq.jpg",0);
 namedWindow("Image");
 imshow("Image", img);
 threshold(img, result, 100, 255, CV_THRESH_BINARY);
 imshow("output", result);
 waitKey(0);
 return 0;
}

2 图像缩放

2.1 基本概念

在计算机图像处理和计算机图形学中,图像缩放(image scaling)是指对数字图像的大小进行调整的过程。图像缩放是一种非平凡的过程,需要在处理效率以及结果的平滑度(smoothness)和清晰度(sharpness)上做一个权衡。当一个图像的大小增加之后,组成图像的像素的可见度将会变得更高,从而使得图像表现得粗糙。相反地,缩小一个图像将会增强它的平滑度和清晰度,让图像看起来更加细腻。OpenCV 提供的 Resize() 函数非常方便而且效率也非常高。

图像缩放是计算机视觉中一个非常常见的操作。它涉及到改变图像的尺寸,可以用来适应不同的显示设备、节省存储空间,或者为了某些处理操作(比如特征提取、物体检测等。

2.2 函数介绍

cpp 复制代码
cv::resize(
    const cv::Mat& src,          // 输入图像
    cv::Mat& dst,                // 输出图像
    cv::Size dsize,              // 输出图像的尺寸,指定宽度和高度
    double fx = 0,               // 水平缩放因子(默认0,表示不改变)
    double fy = 0,               // 垂直缩放因子(默认0,表示不改变)
    int interpolation = cv::INTER_LINEAR // 插值方法,默认线性插值
);

src:输入图像(可以是彩色图像或灰度图像)。

dst:输出图像,存储缩放后的结果。

dsize:目标图像的大小(cv::Size(width, height)),你可以指定宽度和高度。

fx、fy:缩放因子。如果你不指定 dsize,可以通过这两个因子来控制宽度和高度的缩放比例。例如,fx = 2 表示宽度放大2倍,fy = 0.5 表示高度缩小为原来的一半。

interpolation:插值方法,用于在缩放过程中生成新的像素值。OpenCV 支持多种插值方法,默认是 线性插值(cv::INTER_LINEAR)。

cpp 复制代码
cv::INTER_NEAREST:最近邻插值。最快,但质量较差,可能导致"锯齿状"边缘。

cv::INTER_LINEAR:双线性插值。常用的默认方法,平衡速度和质量,适用于大多数场景。

cv::INTER_CUBIC:三次插值。效果更好,但速度稍慢,适合对质量要求较高的场景。

cv::INTER_LANCZOS4:Lanczos插值。最优的质量,但计算量最大,适用于高质量要求的缩放。

2.3 基本参考代码

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取图像
    cv::Mat image = cv::imread("image.jpg");
    if (image.empty()) {
        std::cerr << "无法读取图像!" << std::endl;
        return -1;
    }

    // 创建一个目标大小
    cv::Size targetSize(800, 600);  // 将图像缩放到 800x600

    // 输出图像
    cv::Mat resizedImage;

    // 使用 cv::resize 进行图像缩放
    cv::resize(image, resizedImage, targetSize, 0, 0, cv::INTER_LINEAR);

    // 显示原图和缩放后的图像
    cv::imshow("原图", image);
    cv::imshow("缩放后的图像", resizedImage);

    cv::waitKey(0);  // 等待用户按键
    return 0;
}
cpp 复制代码
cv::Mat resizedImage;
cv::resize(image, resizedImage, cv::Size(), 0.5, 0.5, cv::INTER_LINEAR);  // 缩小到原来的一半

2.4 pyrUp 和 pyrDown 函数

pyrUp 和 pyrDown 是 OpenCV 中常用的图像金字塔(Pyramid)操作函数,用于分别对图像进行上采样和下采样。这两个函数是高效实现金字塔图像缩放的工具,通常用于多尺度图像处理,如图像金字塔、图像金字塔加速的图像匹配和特征提取等。

图像金字塔是一种多层次的图像表示方法,它将图像通过不同的分辨率进行降采样和上采样,形成一个金字塔结构。每一层都是前一层的缩小或放大的版本。

金字塔下采样(PyrDown):逐渐降低图像的分辨率,形成越来越小的图像。

金字塔上采样(PyrUp):逐渐提高图像的分辨率,形成越来越大的图像。

2.5 函数介绍

  1. cv::pyrDown 用于图像的 下采样(缩小),它通过 高斯滤波 平滑图像,然后对其进行 降采样。
cpp 复制代码
cv::pyrDown(const cv::Mat& src, cv::Mat& dst, cv::Size dstsize = cv::Size());

src:输入图像。

dst:输出图像(下采样后的图像)。

dstsize:输出图像的目标尺寸。如果不指定,OpenCV 会自动计算。

默认情况下,目标图像的尺寸是源图像尺寸的一半(宽和高分别缩小为原来的一半)。

  1. cv::pyrUp 用于图像的 上采样(放大),它首先会通过 插值 放大图像,然后进行 高斯平滑 来减少模糊。
cpp 复制代码
cv::pyrUp(const cv::Mat& src, cv::Mat& dst, cv::Size dstsize = cv::Size());

src:输入图像。

dst:输出图像(上采样后的图像)。

dstsize:输出图像的目标尺寸。如果不指定,OpenCV 会自动计算。

默认情况下,目标图像的尺寸是源图像尺寸的两倍(宽和高分别增大为原来的两倍)。

功能:

将图像的大小放大一倍,并通过高斯滤波对图像进行平滑,防止在放大过程中产生锯齿和过度模糊。

2.6 参考代码

c 复制代码
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
Mat src, dst, tmp;
const char* window_name = "Pyramids Demo";
int main( int argc, char** argv )
{
 printf( "\n Zoom In-Out demo \n " );
 printf( "------------------ \n" );
 printf( " * [u] -> Zoom in \n" );
 printf( " * [d] -> Zoom out \n" );
 printf( " * [ESC] -> Close program \n \n" );
 src = imread( "cyq.jpg" );
 if( !src.data ){
 printf(" No data! -- Exiting the program \n");
 return -1;
 }
 tmp = src;
 dst = tmp;
 namedWindow( window_name, CV_WINDOW_AUTOSIZE );
 imshow( window_name, dst );
 while( true )
 {
 int c;
 c = waitKey(10);
 if( (char)c == 27 )
 break;
 if( (char)c == 'u' ){ 
 pyrUp( tmp, dst, Size( tmp.cols*2, tmp.rows*2 ) );
 printf( "** Zoom In: Image x 2 \n" );
 }
 else if( (char)c == 'd' ) {
 yrDown( tmp, dst, Size( tmp.cols/2, tmp.rows/2 ) );
 printf( "** Zoom Out: Image / 2\n");
 }
 imshow( window_name, dst );
 tmp = dst;
 }
 return 0;
}

2.7 总结

🔧 resize 是你万能的图像尺寸调节器;

📉 pyrDown 是模糊又平滑的降采样器;

📈 pyrUp 是温柔的图像放大器(带模糊,不够清晰)

相关推荐
500佰1 分钟前
AI提示词(Prompt)设计优化方案 | 高效使用 AI 工具
java·人工智能·prompt·ai编程
机器之心1 分钟前
近 40 年前「拉马努金图」概率的赌局,被姚班校友黄骄阳等三位数学家用物理方法终结
人工智能·openai
IceTeapoy8 分钟前
【RL】强化学习入门(一):Q-Learning算法
人工智能·算法·强化学习
新智元10 分钟前
o3 被曝「无视」前成果?华人博士生实名指控,谢赛宁等大牛激烈争辩
人工智能·openai
新智元11 分钟前
95 后打造世界首个行动型浏览器——Fellou,从「浏览」到「行动」一键直达!
人工智能·openai
新智元15 分钟前
硅谷 AI 初创要让 60 亿人失业,网友痛批人类叛徒!Jeff Dean 已投
人工智能·openai
haochengxia24 分钟前
vLLM V1 KV Cache Manager 源码学习
人工智能
黑心萝卜三条杠28 分钟前
解锁高性能,YOLOv8 部署至 Jetson Orin Nano 开发板的全攻略
人工智能
小oo呆29 分钟前
【自然语言处理与大模型】Linux环境下Ollama下载太慢了该怎么处理?
linux·服务器·人工智能
CoovallyAIHub29 分钟前
YOLO版本迷信终结!11领域398万实例实测:告诉你的场景该用哪个版本?
opencv·算法·计算机视觉