OpenCV 图像变换与处理实战

OpenCV快速通关

第一章:OpenCV 简介与环境搭建
第二章:OpenCV 图像基本操作
第三章:OpenCV 图像变换与处理实战


OpenCV 图像变换与处理实战

  • OpenCV快速通关
  • OpenCV 图像变换与处理实战
    • 一、OpenCV 基础与图像处理概览
    • 二、图像变换理论精析
    • 三、图像增强与特征提取理论
    • 三、实例分析
      • 1. 定义常量 `M_PI`
      • 2. 重映射图像创建波形效果
      • 3. 缩放图像
      • 4. 旋转图像
      • 5. 颜色变换(灰度图)
      • 6. 边缘检测
      • 7. 高斯模糊
      • 8. 图像锐化
      • 9. 颜色反转
    • 四、主函数实现
    • 五、总结


OpenCV 图像变换与处理实战

  在计算机视觉的绚丽舞台上,OpenCV 无疑是一颗耀眼的明星,它赋予开发者操控图像、挖掘视觉信息的超强能力。在正式深入那些令人惊叹的代码实例前,咱们先来夯实理论基础,为后续实操筑牢根基。

一、OpenCV 基础与图像处理概览

OpenCV(Open Source Computer Vision Library),开源计算机视觉库,犹如一座装满图像处理 “神器” 的百宝箱。历经多年迭代、无数开发者打磨,它横跨多平台,用 C++、Python 等热门语言编写接口,贴合不同编程习惯,揽下计算机视觉八成基础任务,从简单图像读取、存储,到复杂目标检测、图像识别,统统不在话下。
图像处理本质是对图像像素的精心雕琢。图像存于计算机里,像整齐排列的 “像素方阵”,每个像素怀揣颜色、亮度信息。咱做图像处理,就是巧妙改变这些像素属性。像调亮度,是给像素亮度值做加法;改颜色,是调配红、绿、蓝分量。手段不同,目的一致:让图像契合特定需求,或美轮美奂,或信息精准。

二、图像变换理论精析

(一)重映射(Remapping)
重映射堪称图像坐标的 “乾坤大挪移”。正常图像像素按行列规则站位,重映射打破常规,依自定义映射规则给像素 “搬家”。核心原理是新建两张和原图像同尺寸 “坐标图”(src_x、src_y),记录新位置,好比导游图,指引像素 “迁移” 方向。这操作实用性拉满,制造波浪、扭曲特效时大显身手,让画面瞬间灵动。

(二)缩放(Scaling)
缩放直白说就是给图像 “放大缩小”。数学上,按比例因子(scale_x、scale_y)改变行列像素数量,近的像素合并变小图,间隔插值变 “长胖” 成大图。插值算法是关键,常见线性插值(cv::INTER_LINEAR),像经验老到的裁缝,凭周边像素信息,算出新增像素 “恰当脸色”,保图像平滑过渡。

(三)旋转(Rotation)
旋转让图像优雅 “转身”。先锁定旋转中心,多为图像几何中心,再用旋转矩阵(由 cv::getRotationMatrix2D 生成)做 “旋转指令”。这矩阵蕴含旋转角度、缩放比例信息,结合仿射变换(cv::warpAffine),像素依指令乖乖就位,画面流畅旋动,毫无违和 “晕车感”。

三、图像增强与特征提取理论

(一)颜色变换(Color Conversion)
颜色空间多如繁星,常见 RGB、HSV、灰度等。RGB 重色彩呈现,HSV 便颜色调整,灰度则聚焦亮度信息,抛弃色彩冗余。像转灰度图,用 cv::cvtColor 一键 “褪色”,按人眼亮度感知规则,加权融合 RGB 值,提取关键亮度,利于后续处理,还能降数据量、提处理速度。

(二)边缘检测(Edge Detection)
边缘是图像 “骨架”,藏关键轮廓信息。边缘检测算法像敏锐侦探,紧盯像素灰度突变处。Canny 算法是王牌,设低、高双阈值,梯度超 “高线” 锁定边缘;在 “低线” 与 “高线” 间,看连接情况甄别;低过 “低线”,直接 pass。经非极大值抑制、双阈值筛选,精准揪出边缘,给目标识别、图像分割铺好路。

(三)高斯模糊(Gaussian Blur)
现实图像常带噪声,像老照片划痕、数码噪点。高斯模糊化身 “美颜磨皮师”,用高斯函数生成权重核,中心像素权重高、周边递减,加权平均周边像素值,模糊图像、柔化噪声,让画面细腻干净,为后续精准处理清障。

(四)图像锐化(Image Sharpening)
锐化是模糊 “克星”,找回图像丢失细节。原理是强化高频分量,弱化低频。靠特制卷积核(如文中 3x3 核)卷积图像,中心像素 “突出”,周边反向调节,反差凸显边缘细节,照片、扫描文档处理后清晰度飙升。

(五)颜色反转(Color Inversion)
颜色反转堪称图像 “镜像世界”,简单粗暴按位取反像素值。白变黑、黑变白,各颜色分量翻转,特定艺术创作、负片效果模拟时,轻松拿捏氛围感。

三、实例分析

1. 定义常量 M_PI

#ifndef M_PI
#define M_PI 3.14159265358979323846 // 如果未定义 M_PI,则手动定义
#endif

这段代码的目的是确保在编译过程中,如果 M_PI 常量未被定义,则手动定义它为圆周率的值。这在一些情况下是必要的,因为不同的编译器和环境可能对某些常量的定义有所不同。

2. 重映射图像创建波形效果

void wave(const cv::Mat& img, cv::Mat& res, const std::string& wave_type, double amplitude, double frequency) {cv::Mat src_x(img.rows, img.cols, CV_32F);cv::Mat src_y(img.rows, img.cols, CV_32F);for (int i = 0; i < img.rows; i++) {for (int j = 0; j < img.cols; j++) {src_x.at<float>(i, j) = static_cast<float>(j);double wave_value = 0.0;if (wave_type == "sine") {wave_value = amplitude * sin(frequency * static_cast<double>(j)); // 正弦波}else if (wave_type == "cosine") {wave_value = amplitude * cos(frequency * static_cast<double>(j)); // 余弦波}else if (wave_type == "triangle") {wave_value = amplitude * (2.0 / M_PI) * asin(sin(frequency * static_cast<double>(j))); // 三角波}else if (wave_type == "sawtooth") {wave_value = amplitude * (2.0 * (j / static_cast<double>(img.cols)) - 1.0); // 锯齿波}src_y.at<float>(i, j) = static_cast<float>(i + wave_value);}}cv::remap(img, res, src_x, src_y, cv::INTER_LINEAR);
}

这个函数用于创建不同类型的波形效果,通过重映射图像的像素坐标来实现。它接受输入图像 img、输出图像 res、波形类型 wave_type、振幅 amplitude 和频率 frequency 作为参数。

首先,创建两个与输入图像大小相同的矩阵 src_xsrc_y,分别用于存储重映射后的 x 和 y 坐标。然后,通过双层循环遍历输入图像的每个像素。对于每个像素,将 src_x 中的对应值设置为当前像素的 x 坐标,并根据 wave_type 的不同计算出波形的值 wave_value。最后,将 src_y 中的对应值设置为当前像素的 y 坐标加上波形值。

最后,使用 cv::remap 函数根据 src_xsrc_y 矩阵对输入图像进行重映射,得到输出图像 res

3. 缩放图像

void scale(const cv::Mat& img, cv::Mat& res, double scale_x, double scale_y) {cv::resize(img, res, cv::Size(), scale_x, scale_y, cv::INTER_LINEAR);
}

这个函数用于缩放图像。它接受输入图像 img、输出图像 res、水平缩放比例 scale_x 和垂直缩放比例 scale_y 作为参数。

使用 cv::resize 函数对输入图像进行缩放,将输出图像的大小设置为输入图像的大小乘以缩放比例。这里使用 cv::INTER_LINEAR 插值方法,以获得较为平滑的缩放效果。

4. 旋转图像

void rotate1(const cv::Mat& img, cv::Mat& res, double angle) {cv::Point2f center(img.cols / 2.0, img.rows / 2.0);cv::Mat rot = cv::getRotationMatrix2D(center, angle, 1.0);cv::warpAffine(img, res, rot, img.size());
}

这个函数用于旋转图像。它接受输入图像 img、输出图像 res 和旋转角度 angle 作为参数。

首先,计算图像的中心坐标。然后,使用 cv::getRotationMatrix2D 函数创建一个旋转矩阵 rot,该矩阵将图像绕中心旋转指定的角度。最后,使用 cv::warpAffine 函数根据旋转矩阵对输入图像进行仿射变换,得到输出图像 res

5. 颜色变换(灰度图)

void grayscale(const cv::Mat& img, cv::Mat& res) {cv::cvtColor(img, res, cv::COLOR_BGR2GRAY);
}

这个函数用于将彩色图像转换为灰度图像。它接受输入图像 img 和输出图像 res 作为参数。

使用 cv::cvtColor 函数将输入图像从 BGR 颜色空间转换为灰度颜色空间,得到输出图像 res

6. 边缘检测

void edge_detection(const cv::Mat& img, cv::Mat& res) {cv::Canny(img, res, 100, 200);
}

这个函数用于进行边缘检测。它接受输入图像 img 和输出图像 res 作为参数。

使用 cv::Canny 函数对输入图像进行边缘检测,该函数接受输入图像、输出图像、低阈值和高阈值作为参数。边缘检测算法会根据像素的梯度强度来确定是否为边缘像素,如果像素的梯度强度大于高阈值,则被认为是边缘像素;如果像素的梯度强度小于低阈值,则被认为不是边缘像素;如果像素的梯度强度在低阈值和高阈值之间,则根据其与边缘像素的连接情况来确定是否为边缘像素。

7. 高斯模糊

void gaussian_blur(const cv::Mat& img, cv::Mat& res) {cv::GaussianBlur(img, res, cv::Size(5, 5), 0);
}

这个函数用于对图像进行高斯模糊处理。它接受输入图像 img 和输出图像 res 作为参数。

使用 cv::GaussianBlur 函数对输入图像进行高斯模糊,该函数接受输入图像、输出图像、模糊核大小和标准差作为参数。这里使用的模糊核大小为 cv::Size(5, 5),标准差为 0,表示由函数自动计算标准差。

8. 图像锐化

void sharpen(const cv::Mat& img, cv::Mat& res) {cv::Mat kernel = (cv::Mat_<float>(3, 3) <<0, -1, 0,-1, 5, -1,0, -1, 0);cv::filter2D(img, res, img.depth(), kernel);
}

这个函数用于对图像进行锐化处理。它接受输入图像 img 和输出图像 res 作为参数。

首先,定义一个 3x3 的锐化内核 kernel。然后,使用 cv::filter2D 函数对输入图像进行卷积操作,该函数接受输入图像、输出图像、图像深度和卷积内核作为参数。这里将输入图像与锐化内核进行卷积,得到输出图像 res,从而实现图像锐化的效果。

9. 颜色反转

void invert_colors(const cv::Mat& img, cv::Mat& res) {cv::bitwise_not(img, res);
}

这个函数用于对图像进行颜色反转处理。它接受输入图像 img 和输出图像 res 作为参数。

使用 cv::bitwise_not 函数对输入图像进行按位取反操作,即将每个像素的颜色值取反,得到输出图像 res

四、主函数实现

int main() {cv::Mat img = cv::imread("E:/pro/sdl_code/res/test_img.png");if (img.empty()) {std::cerr << "Error: Image not found." << std::endl;return -1;}cv::Mat sine_wave_img, cosine_wave_img, triangle_wave_img, sawtooth_wave_img, scale_img, rotate_img, gray_img, edge_img, blur_img, sharp_img, invert_img;// 不同波形效果wave(img, sine_wave_img, "sine", 20, 0.1);        // 正弦波wave(img, cosine_wave_img, "cosine", 20, 0.1);    // 余弦波wave(img, triangle_wave_img, "triangle", 20, 0.1); // 三角波wave(img, sawtooth_wave_img, "sawtooth", 20, 10); // 锯齿波// 缩放图像scale(img, scale_img, 0.5, 0.5);// 旋转图像rotate1(img, rotate_img, 45);// 颜色变换(灰度图)grayscale(img, gray_img);// 边缘检测edge_detection(img, edge_img);// 高斯模糊gaussian_blur(img, blur_img);// 图像锐化sharpen(img, sharp_img);// 颜色反转invert_colors(img, invert_img);// 显示所有效果cv::imshow("Original Image", img);cv::imshow("Sine Wave Effect", sine_wave_img);cv::imshow("Cosine Wave Effect", cosine_wave_img);cv::imshow("Triangle Wave Effect", triangle_wave_img);cv::imshow("Sawtooth Wave Effect", sawtooth_wave_img);cv::imshow("Scaled Image", scale_img);cv::imshow("Rotated Image", rotate_img);cv::imshow("Grayscale Image", gray_img);cv::imshow("Edge Detection", edge_img);cv::imshow("Gaussian Blur", blur_img);cv::imshow("Sharpened Image", sharp_img);cv::imshow("Inverted Colors", invert_img);cv::waitKey(0);// 保存结果图像//cv::imwrite("output_wave_image.jpg", wave_img);//cv::imwrite("output_scaled_image.jpg", scale_img);//cv::imwrite("output_rotated_image.jpg", rotate_img);//cv::imwrite("output_grayscale_image.jpg", gray_img);//cv::imwrite("output_edge_detection.jpg", edge_img);//cv::imwrite("output_gaussian_blur.jpg", blur_img);//cv::imwrite("output_sharpened_image.jpg", sharp_img);//cv::imwrite("output_inverted_colors.jpg", invert_img);return 0;
}

主函数首先读取输入图像,如果图像读取失败,则输出错误信息并返回 -1。然后,创建多个输出图像用于存储不同的处理效果。接下来,分别调用不同的函数对输入图像进行处理,得到各种效果的输出图像。最后,显示所有的图像,并等待用户按下任意键退出程序。如果需要保存结果图像,可以取消注释相应的代码行。

在这里插入图片描述

五、总结

本文介绍了如何使用 OpenCV 实现多种图像变换和处理效果,包括重映射图像创建波形效果、缩放图像、旋转图像、颜色变换、边缘检测、高斯模糊、图像锐化和颜色反转等。通过这些功能,我们可以对图像进行各种操作,从而实现不同的视觉效果。在实际应用中,可以根据具体需求选择合适的图像变换和处理方法,以达到更好的效果。

希望本文对大家学习和使用 OpenCV 有所帮助。如果有任何问题或建议,欢迎在评论区留言。首先介绍了 OpenCV 的重要性和本文要展示的内容。接着进行环境准备的说明,包括安装 OpenCV 和 C++编译器。然后对关键代码进行详细分析,分别解释了定义常量 M_PI、各种图像变换和处理函数的作用及实现原理。最后展示了主函数的实现,包括读取图像、创建输出图像、调用各种处理函数、显示图像和等待用户操作等。整体文章结构清晰,按照介绍、准备、分析、实现和总结的顺序进行撰写,以帮助读者更好地理解 OpenCV 的图像变换和处理功能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu22.04安装docker desktop遇到的bug

1. 确认已启用 KVM 虚拟化 如果加载了模块&#xff0c;输出应该如下图。说明 Intel CPU 的 KVM 模块已开启。 否则在VMware开启宿主机虚拟化功能&#xff1a; 2. 下一步操作&#xff1a; Ubuntu | Docker Docs 3. 启动Docker桌面后发现账户登陆不上去&#xff1a; Sign in | …

【深度学习入门】深度学习介绍

1.1 深度学习介绍 学习目标 目标 知道深度学习与机器学习的区别了解神经网络的结构组成知道深度学习效果特点 应用 无 区别 特征提取方面 机器学习的特征工程步骤是要靠手动完成的&#xff0c;而且需要大量领域专业知识深度学习通常由多个层组成&#xff0c;它们通常将更简…

实现按键按下(低电平)检测到下降沿

按照流程进行编程 步骤1&#xff1a; 初始化函数 包括时基工作参数配置 输入通道配置 更新中断使能 使能捕获、捕获中断及计数器 HAL_TIM_IC_Init(&ic_handle) //时基参数配置 HAL_TIM_IC_ConfigChannel(&ic_handle,&ic_config,TIM_CHANNEL_2) //输…

汽车车牌标记支持YOLO,COCO,VOC三种格式标记,4000张图片的数据集

本数据集支持YOLO&#xff0c;COCO&#xff0c;VOC三种格式标记汽车车牌&#xff0c;无论是新能源汽车还是油车都能识别标记&#xff0c;该数据集一共包含4000张图片 数据集分割 4000总图像数 训练组 70&#xff05; 2800图片 有效集 20&#xff05; 800图片 测…

游秦岭山感

巍乎高哉&#xff01; 悠悠大秦岭 佑吾华夏之根脉 八水润之 泽万物而赋予生机 于万山之山中 享自然之美于万物 西有昆仑祖龙脉 东有秦岭护关中 绿水青山国之本 万山长青谋发展 旭日东升耀中华 固我山河永泰安 你我同行共保护 关中龙脉更兴旺

阿里云-通义灵码:测试与实例展示

目录 一.引子 二.例子 三.优点 四.其他优点 五.总结 一.引子 在软件开发的广袤天地中&#xff0c;阿里云通义灵码宛如一座蕴藏无尽智慧的宝库&#xff0c;等待着开发者们去深入挖掘和探索。当我们跨越了入门的门槛&#xff0c;真正开始使用通义灵码进行代码生成和开发工作…

微信小程序中使用miniprogram-sm-crypto实现SM4加密攻略

在微信小程序开发过程中&#xff0c;数据安全至关重要。本文将为大家介绍如何在微信小程序中使用miniprogram-sm-crypto插件进行SM4加密&#xff0c;确保数据传输的安全性。 一、SM4加密简介 SM4是一种对称加密算法&#xff0c;由国家密码管理局发布&#xff0c;适用于商密领…

使用 Ansys Fluent 对气体泄漏检测进行建模

了解使用 Ansys Fluent 仿真气体泄漏和确保安全的前沿技术。 挑战 气体泄漏对人类安全和环境构成重大风险。及早检测气体泄漏可以防止潜在的灾难&#xff0c;包括爆炸、火灾和有毒物质暴露。有效的气体泄漏检测系统对于石油和天然气、化学加工和住宅基础设施等行业至关重要。…

QT图形/视图架构详解(一)

场景、视图与图形项 图形/视图架构主要由 3 个部分组成&#xff0c;即场景、视图和图形项&#xff0c;三者的关系如图所示&#xff1a; 场景、视图和图形项的关系 场景&#xff08;QGraphicsScene 类&#xff09; 场景不是界面组件&#xff0c;它是不可见的。场景是一个抽象的…

LLM之RAG实战(五十)| FastAPI:构建基于LLM的WEB接口界面

FastAPI是WEB UI接口&#xff0c;随着LLM的蓬勃发展&#xff0c;FastAPI的生态也迎来了新的机遇。本文将围绕FastAPI、OpenAI的API以及FastCRUD&#xff0c;来创建一个个性化的电子邮件写作助手&#xff0c;以展示如何结合这些技术来构建强大的应用程序。 下面我们开始分步骤操…

Maven学习(Maven项目模块化。模块间“继承“机制。父(工程),子项目(模块)间聚合)

目录 一、Maven项目模块化&#xff1f; &#xff08;1&#xff09;基本介绍。 &#xff08;2&#xff09;汽车模块化生产再聚合组装。 &#xff08;3&#xff09;Maven项目模块化图解。 1、maven_parent。 2、maven_pojo。 3、maven_dao。 4、maven_service。 5、maven_web。 6…

CNAS软件实验室认可费用清单,如何规划预算方案?

CNAS软件实验室在申请认可前&#xff0c;需要按照CNAS相关认可文件的要求&#xff0c;建立完善的CNAS软件实验室质量管理体系&#xff0c;试运行六个月&#xff0c;且覆盖全部质量要素后&#xff0c;向CNAS认可委提交申请&#xff0c;等待专家的审查。在前期的筹备工作中&#…

【2024 Dec 超实时】编辑安装llama.cpp并运行llama

首先讲一下环境 这是2024 年12月&#xff0c;llama.cpp 的编译需要cmake 呜呜呜 网上教程都是make 跑的。反正我现在装的时候make已经不再适用了&#xff0c;因为工具的版本&#xff0c;捣鼓了很久。 ubuntu 18 conda env内置安装。 以下是可以完美编译llama.cpp的测试工具版…

优化移动端H5:常见问题与解决方案

移动端H5开发中的“坑”与解决方案 本文介绍了开发中遇到的几个关于移动端H5开发中的小问题&#xff0c;以及解决的方法。 一、iOS滑动不流畅问题 在iOS设备上&#xff0c;H5页面的滑动效果有时会出现不流畅的情况&#xff0c;特别是在页面高度超过一屏时。这通常是由于iOS的…

Visual Studio 2022+CMake配置PCL1.14.1

前言 本教程只是提供高效的PCL配置流程&#xff0c;不提供Qt环境配置&#xff0c;如果需要GUI界面&#xff0c;则需要自寻查找Cmake配置QT的教程。请相信&#xff0c;在CMake之下没有任何事是困难的&#xff0c;最困难的工作已经由前辈们完成。因此&#xff0c;对于C用户来说学…

C++多线程实战:掌握图像处理高级技巧

文章结尾有最新热度的文章,感兴趣的可以去看看。 本文是经过严格查阅相关权威文献和资料,形成的专业的可靠的内容。全文数据都有据可依,可回溯。特别申明:数据和资料已获得授权。本文内容,不涉及任何偏颇观点,用中立态度客观事实描述事情本身 导读 在当今的计算世界中,…

C++在关键嵌入式软件领域逐步取代 Ada 的演进历程

第一章&#xff1a;引言 1.1 Ada 与 C在嵌入式系统中的角色 在嵌入式系统开发领域的漫长演进历程中&#xff0c;Ada 与 C宛如两颗璀璨而又各具特色的星辰&#xff0c;交替影响着该领域的发展轨迹。它们不仅代表了两种不同的编程哲学&#xff0c;也反映了不同时期对软件可靠性…

高项 - 法律法规与标准规范

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 博文更新参考时间点&#xff1a;2024-12 高项 - 章节与知识点汇总&#xff1a;点击跳转 文章目录 高项 - 法律法规与标准规范法律法规民法典&#xff08;合同编&#xff09;招标投标法政府采购法专利法著作权法商…

EXCEL数据清洗的几个功能总结备忘

目录 0 参考教材 1 用EXCEL进行数据清洗的几个功能 2 删除重复值&#xff1a; 3 找到缺失值等 4 大小写转换 5 类型转化 6 识别空格 0 参考教材 精通EXCEL数据统计与分析&#xff0c;中国&#xff0c;李宗璋用EXCEL学统计学&#xff0c;日EXCEL统计分析与决策&#x…

基于小程序实现地图定位、轨迹绘制、地图标点、快捷导航、唤醒导航APP、开箱即用

目录 前言研究背景与意义研究目标与内容研究方法与技术路线小程序地图组件介绍定位技术与原理轨迹绘制技术地图标注与标记功能地图定位与轨迹绘制功能实现定位功能设计与实现获取用户当前位置总结说明代码块前言 研究背景与意义 地图定位和轨迹追踪作为智能手机中常见的功能之…