机器视觉-7 检测原理之预处理(图像增强)

在图像处理领域,图像增强是一个非常重要的技术,目的是通过调整图像的某些特征来改善图像的视觉效果,或为后续的图像分析和处理做准备。在 OpenCV 中,C++ 提供了多种图像增强方法,包括直方图均衡化、对比度拉伸、锐化、边缘增强等操作。下面详细介绍 C++ 中使用 OpenCV 进行图像增强的常用方法,并附上代码示例。

1. 直方图均衡化 (Histogram Equalization)

直方图均衡化是一种常用的图像增强技术,主要用于改善图像的对比度,使图像的灰度值分布更加均匀,适合处理光照不均的图像。

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {// 读取灰度图像Mat image = imread("image.jpg", IMREAD_GRAYSCALE);if (image.empty()) {return -1;}// 直方图均衡化Mat equalized_image;equalizeHist(image, equalized_image);// 显示原图和均衡化后的图像imshow("Original Image", image);imshow("Equalized Image", equalized_image);waitKey(0);return 0;
}

主要函数:
  • equalizeHist():用于对图像进行直方图均衡化。只能应用于灰度图像。

2. CLAHE (对比度受限自适应直方图均衡化)

CLAHE(Contrast Limited Adaptive Histogram Equalization)是一种改进的直方图均衡化方法,它将图像分成小块(称为 tiles),分别对每个块进行直方图均衡化,避免了传统均衡化中可能产生的过度增强现象。

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {// 读取灰度图像Mat image = imread("image.jpg", IMREAD_GRAYSCALE);if (image.empty()) {return -1;}// 创建CLAHE对象Ptr<CLAHE> clahe = createCLAHE();clahe->setClipLimit(2.0); // 设置对比度限制Mat clahe_image;clahe->apply(image, clahe_image);// 显示原图和CLAHE增强后的图像imshow("Original Image", image);imshow("CLAHE Image", clahe_image);waitKey(0);return 0;
}

主要函数:
  • createCLAHE():创建一个 CLAHE 对象。
  • setClipLimit():设置 CLAHE 的对比度限制。

3. 亮度与对比度调整 (Brightness and Contrast Adjustment)

通过线性变换可以直接调整图像的亮度和对比度。调整亮度通常是在图像上加上一个常数,而调整对比度则是对图像乘以一个系数。

公式为:

new_image=α×image+β

其中,alpha 是对比度因子,beta 是亮度偏移值。

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {// 读取图像Mat image = imread("image.jpg");if (image.empty()) {return -1;}Mat new_image = Mat::zeros(image.size(), image.type());double alpha = 1.5; // 对比度因子int beta = 50;      // 亮度偏移// 调整亮度与对比度for (int y = 0; y < image.rows; y++) {for (int x = 0; x < image.cols; x++) {for (int c = 0; c < 3; c++) {new_image.at<Vec3b>(y, x)[c] = saturate_cast<uchar>(alpha * image.at<Vec3b>(y, x)[c] + beta);}}}imshow("Original Image", image);imshow("New Image", new_image);waitKey(0);return 0;
}

主要函数:
  • saturate_cast<uchar>:用于防止数值溢出(防止像素值超出 0-255 的范围)。

4. 锐化 (Sharpening)

通过应用锐化滤波器,可以增强图像的细节,使图像看起来更清晰。常见的锐化卷积核如下:

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat image = imread("image.jpg");if (image.empty()) {return -1;}// 定义锐化卷积核Mat kernel = (Mat_<float>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);// 应用滤波器进行锐化Mat sharpened_image;filter2D(image, sharpened_image, -1, kernel);imshow("Original Image", image);imshow("Sharpened Image", sharpened_image);waitKey(0);return 0;
}

主要函数:
  • filter2D():用于应用自定义的卷积核进行滤波。

5. 边缘检测 (Edge Detection)

图像增强中常用的边缘检测算法包括 Sobel 算子和 Canny 边缘检测。

Sobel 算子:

Sobel 算子是基于梯度的边缘检测方法,计算图像在水平方向和垂直方向上的梯度,并结合这两个方向的梯度幅值来找到边缘。

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat image = imread("image.jpg", IMREAD_GRAYSCALE);if (image.empty()) {return -1;}Mat grad_x, grad_y;Mat abs_grad_x, abs_grad_y, grad;// 计算 x 方向的梯度Sobel(image, grad_x, CV_16S, 1, 0, 3);convertScaleAbs(grad_x, abs_grad_x);// 计算 y 方向的梯度Sobel(image, grad_y, CV_16S, 0, 1, 3);convertScaleAbs(grad_y, abs_grad_y);// 合并梯度addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);imshow("Original Image", image);imshow("Sobel Edge Detection", grad);waitKey(0);return 0;
}

主要函数:
  • Sobel():计算图像的 Sobel 梯度。
  • convertScaleAbs():将计算出的梯度值转换为 8 位无符号类型。
Canny 边缘检测:

Canny 算法是一种经典的多级边缘检测算法,常用于检测图像中的明显边缘。

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat image = imread("image.jpg", IMREAD_GRAYSCALE);if (image.empty()) {return -1;}Mat edges;// 使用Canny边缘检测Canny(image, edges, 100, 200);imshow("Original Image", image);imshow("Canny Edge Detection", edges);waitKey(0);return 0;
}

主要函数:
  • Canny():OpenCV 中的 Canny 边缘检测函数。

6. 图像伽马校正 (Gamma Correction)

伽马校正用于调整图像的亮度或对比度,它是非线性的图像增强方法。通过控制伽马值,可以增强图像的暗部细节或亮部细节。

伽马校正公式:

代码实现:
#include <opencv2/opencv.hpp>
#include <cmath>
using namespace cv;int main() {Mat image = imread("image.jpg");if (image.empty()) {return -1;}Mat gamma_corrected_image;image.convertTo(gamma_corrected_image, CV_32F, 1.0 / 255); // 归一化pow(gamma_corrected_image, 0.5, gamma_corrected_image);     // 伽马校正,gamma = 0.5gamma_corrected_image.convertTo(gamma_corrected_image, CV_8U, 255); // 反归一化imshow("Original Image", image);imshow("Gamma Corrected Image", gamma_corrected_image);waitKey(0);return 0;
}


7. 拉普拉斯锐化 (Laplacian Sharpening)

拉普拉斯算子是一种二阶导数算子,常用于增强图像的边缘特征。它通过计算图像中像素点的二阶导数来检测边缘。使用拉普拉斯算子可以有效增强图像中的边缘,使图像显得更加清晰。

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat image = imread("image.jpg", IMREAD_GRAYSCALE);if (image.empty()) {return -1;}Mat laplacian_image;// 使用拉普拉斯算子进行锐化Laplacian(image, laplacian_image, CV_16S, 3);convertScaleAbs(laplacian_image, laplacian_image);  // 转换为 8 位图像imshow("Original Image", image);imshow("Laplacian Sharpening", laplacian_image);waitKey(0);return 0;
}

主要函数:
  • Laplacian():OpenCV 中的拉普拉斯算子计算函数。
  • convertScaleAbs():将拉普拉斯算子的输出转换为 8 位图像。

8. 非局部均值去噪 (Non-Local Means Denoising)

非局部均值 (Non-Local Means, NLM) 去噪是一种高级去噪算法。它通过对图像中相似的局部区域进行加权平均来去除噪声,同时最大程度地保留细节。

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat image = imread("image.jpg");if (image.empty()) {return -1;}Mat denoised_image;// 使用非局部均值去噪fastNlMeansDenoisingColored(image, denoised_image, 10, 10, 7, 21);imshow("Original Image", image);imshow("Denoised Image", denoised_image);waitKey(0);return 0;
}

主要参数:
  • h:控制强度,值越大,去噪效果越强,但细节损失越大。
  • fastNlMeansDenoisingColored():OpenCV 中用于彩色图像去噪的函数。

9. 仿射变换 (Affine Transformation)

仿射变换是一种几何图像增强技术,它可以对图像进行旋转、缩放、平移、剪切等变换。仿射变换可以用 2x3 的矩阵来表示。

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat image = imread("image.jpg");if (image.empty()) {return -1;}// 定义仿射变换矩阵Point2f srcTri[3], dstTri[3];srcTri[0] = Point2f(0, 0);srcTri[1] = Point2f(image.cols - 1, 0);srcTri[2] = Point2f(0, image.rows - 1);dstTri[0] = Point2f(0, image.rows * 0.33);dstTri[1] = Point2f(image.cols * 0.85, image.rows * 0.25);dstTri[2] = Point2f(image.cols * 0.15, image.rows * 0.7);Mat warp_mat = getAffineTransform(srcTri, dstTri);Mat warp_dst = Mat::zeros(image.rows, image.cols, image.type());// 应用仿射变换warpAffine(image, warp_dst, warp_mat, warp_dst.size());imshow("Original Image", image);imshow("Affine Transformed Image", warp_dst);waitKey(0);return 0;
}

主要函数:
  • getAffineTransform():生成仿射变换矩阵。
  • warpAffine():应用仿射变换到图像。

10. 透视变换 (Perspective Transformation)

透视变换是一种几何变换,用于校正图像的透视失真。它通过 3x3 的变换矩阵将图像中的一个四边形映射为另一个四边形。

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat image = imread("image.jpg");if (image.empty()) {return -1;}// 定义源图像和目标图像的 4 个点Point2f srcQuad[4], dstQuad[4];srcQuad[0] = Point2f(0, 0);srcQuad[1] = Point2f(image.cols - 1, 0);srcQuad[2] = Point2f(image.cols - 1, image.rows - 1);srcQuad[3] = Point2f(0, image.rows - 1);dstQuad[0] = Point2f(image.cols * 0.1, image.rows * 0.33);dstQuad[1] = Point2f(image.cols * 0.9, image.rows * 0.25);dstQuad[2] = Point2f(image.cols * 0.8, image.rows * 0.9);dstQuad[3] = Point2f(image.cols * 0.2, image.rows * 0.7);// 获取透视变换矩阵Mat warp_mat = getPerspectiveTransform(srcQuad, dstQuad);Mat warp_dst = Mat::zeros(image.rows, image.cols, image.type());// 应用透视变换warpPerspective(image, warp_dst, warp_mat, warp_dst.size());imshow("Original Image", image);imshow("Perspective Transformed Image", warp_dst);waitKey(0);return 0;
}

主要函数:
  • getPerspectiveTransform():生成透视变换矩阵。
  • warpPerspective():应用透视变换到图像。

11. 拉普拉斯金字塔 (Laplacian Pyramid)

拉普拉斯金字塔是一种用于图像多分辨率表示的技术,常用于图像增强、图像融合等领域。金字塔的每一层都是对上一层图像的降采样结果。

代码实现:
#include <opencv2/opencv.hpp>
using namespace cv;int main() {Mat image = imread("image.jpg");if (image.empty()) {return -1;}Mat down, up;// 降采样pyrDown(image, down);// 再次升采样pyrUp(down, up);imshow("Original Image", image);imshow("PyrDown Image", down);imshow("PyrUp Image", up);waitKey(0);return 0;
}

主要函数:
  • pyrDown():降采样图像。
  • pyrUp():升采样图像。

总结

OpenCV 提供了丰富的图像增强工具,涵盖了从基本的亮度、对比度调整,到复杂的去噪、变换等高级操作。通过这些方法,用户可以大大改善图像质量,或为后续的计算机视觉任务做准备。结合不同的图像增强技术,能够帮助解决各种复杂的图像处理问题。

  • 直方图均衡化:改善对比度,适合光照不均的图像。
  • CLAHE:自适应直方图均衡化,适合复杂的光照条件。
  • 亮度与对比度调整:直接线性调整图像的亮度和对比度。
  • 锐化:增强图像的边缘和细节。
  • 边缘检测:检测图像中的显著边缘。
  • 伽马校正:非线性调整图像的亮度,适合暗部细节增强。
  • 拉普拉斯锐化:增强图像边缘。
  • 非局部均值去噪:有效去除噪声,同时保留细节。
  • 仿射与透视变换:用于图像几何变换。
  • 金字塔技术:图像的多分辨率表示,用于增强和压缩。

这些增强方法在实际应用中可以组合使用,根据图像的特点选择适当的算法来达到最佳效果。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

双向链表-

链表特性&#xff1a;带头/不带头 循环/非循环 --->排列组合后&#xff0c;共有8种链表结构 一.双向链表的定义 前一个节点存了后一个节点的地址&#xff0c;后一个节点也存了前一个节点的地址&#xff0c;即循环链表 二.代码解析 //双向链表 //与非循环链表区别&#…

面试官:Spring是如何解决循依赖问题?

Spring 的循环依赖一直都是 Spring 中一个很重要的话题&#xff0c;一方面是 Spring 为了解决循环依赖做了很多工作&#xff0c;另一个方面是因为它是面试 Spring 的常客&#xff0c;因为他要求你看过 Spring 的源码&#xff0c;如果没有看过 Spring 源码你基本上是回答不了这个…

【Java】线程暂停比拼:wait() 和 sleep()的较量

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持&#xff01; 在Java多线程编程中&#xff0c;合理地控制线程的执行是至关重要的。wait()和sleep()是两个常用的方法&#xff0c;它们都可以用来暂停线程的执行&#xff0c;但它们之间存在着显著的差异。本文将详…

移动技术开发:RecyclerView瀑布流水果列表

1 实验名称 RecyclerView瀑布流水果列表 2 实验目的 掌握RecyclerView控件的实现方法和基本应用 3 实验源代码 布局文件代码&#xff1a; activity_main&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android&q…

Mac系统Docker中SQLserver数据库文件恢复记录

Mac系统Docker中SQLserver数据库文件恢复记录 Mac想要安装SQLsever&#xff0c;通过docker去拉去镜像是最简单方法。 一、下载Docker Docker 下载安装&#xff1a; 需要‘科学上网’ 才能访问到docker官网。&#xff08; https://docs.docker.com/desktop/install/mac-ins…

18.2K Star,AI 高效视频监控摄像头

Hi&#xff0c;骚年&#xff0c;我是大 G&#xff0c;公众号「GitHub 指北」会推荐 GitHub 上有趣有用的项目&#xff0c;一分钟 get 一个优秀的开源项目&#xff0c;挖掘开源的价值&#xff0c;欢迎关注。 导语 在家庭和企业安防领域&#xff0c;实时视频监控是保障安全的核…

2024 SNERT 预备队招新 CTF 体验赛-Web

目录 1、robots 2、NOF12 3、get_post 4、好事慢磨 5、uploads 6、rce 7、ezsql 8、RCE 1、robots robots 协议又叫爬虫协议&#xff0c;访问 robots.txt 继续访问 /JAY.php 拿到 flag&#xff1a;flag{hello_Do_YOU_KONw_JAY!} 2、NOF12 F12 和右键都被禁用 方法&#…

22、Raven2

难度 中 目标 root权限 4个flag 使用Virtualbox启动 kali 192.168.86.105 靶机 192.168.86.106 信息收集 看到111端口有一个rpc相关的东西&#xff0c;去网上查看了一下是什么服务 通过在网上搜索发现这是一个信息泄露的漏洞&#xff0c;上面的这个端口其实就是泄露的端口和…

【Spring 底层原理】手搓一个Spring框架

文章目录 准备工作Spring 框架到底在干啥&#xff1f;几个概念辨析注解的定义自定义核心注解配置类启动类辅助类 Spring 容器XxxAware 回调机制初始化机制前置、后置处理器完整的容器代码源码下载 最近工作接触到的知识比较底层&#xff0c;因此为了突破瓶颈&#xff0c;彻底搞…

ubuntu+MobaXterm+ssh+运行Qt(成功版)

点击上方"蓝字"关注我们 01、ubuntu连接SSH >>> 通过串口工具连接ubuntu 登录 解决连接不上的问题 检查 SSH 服务:确保目标机器上 SSH 服务已启动。你可以在目标机器上运行以下命令: sudo systemctl status ssh 如果没有运行,可以使用以下命令启动 SSH …

英特尔AI加速器Gaudi 3下周发布,挑战NVIDIA统治地位!

英特尔正稳步推进其2024年计划&#xff0c;备受瞩目的AI加速器Gaudi3预计将于下周震撼登场。这款被誉为英特尔AI英雄的产品&#xff0c;专注于处理大规模训练和推理任务&#xff0c;拥有无与伦比的扩展能力。面对市场对高效能半导体的旺盛需求&#xff0c;英特尔首席执行官帕特…

FX5 CPU模块和以太网模块的以太网通信功能

FX5 CPU模块和以太网模块的以太网通信功能的概要如下所示。 CPU模块的内置以太网端口的通信规格如下所示。 1、与MELSOFT的直接连接 不使用集线器&#xff0c;用1根以太网电缆直接连接以太网搭载模块与工程工具(GX Torks3)。无需设定IP地址&#xff0c;仅连接目标指定即可进行…

无服务器计算构建人工智能管理区块链系统

图片发自简书App 图片发自简书App 本发明属于网络版权管理技术领域&#xff0c;特别涉及一种以交易信息作 为唯一标准发行虚拟币的区块链系统。 背景技术 数字代币如比特币、以太坊等是区块链技术的实现方式之一&#xff0c;目 标是取代法定货币流通&#xff0c;通过“挖矿”的…

前端-js例子:收钱转账

支付宝转账 在这里用到周期定时器setInterval(function,time)&#xff0c;设置达到目标钱数时停止定时器。 点击转账按钮时&#xff0c;开始函数显示。 同时要确定输入框里输入的是数字。&#xff08;有一定容错&#xff09; window.onloadfunction(){var btn document.que…

什么是慢充优惠话费充值api?如何选择平台

一、话费充值api的定义 话费充值api是一种能够让开发者将话费充值功能集成到自己的平台的接口。通过接入话费充值api接口&#xff0c;就能够实现话费充值平台的搭建&#xff0c;从而为用户提供话费充值服务&#xff0c;这一接口主要适用于对话费充值有长期稳定需求的企业或者商…

K8s容器运行时,移除Dockershim后存在哪些疑惑?

K8s容器运行时&#xff0c;移除Dockershim后存在哪些疑惑&#xff1f; 大家好&#xff0c;我是秋意零。 K8s版本截止目前&#xff08;24/09&#xff09;已经发布到了1.31.x版本。早在K8s版本从1.24.x起&#xff08;22/05&#xff09;&#xff0c;默认的容器运行时就不再是Doc…

排序-----归并排序(递归版)

核心思想&#xff1a;假设数组前后两部分各自有序&#xff0c;然后各定义两个指针&#xff0c;谁小谁放到新开辟的数组里面&#xff0c;最后把新开辟的数组赋值给原数组就完成了。要使前后两部分有序就采用递归的方式&#xff0c;不断往下划分块&#xff0c;最后一层划分为两个…

01 基础request

目录 类 WxRequest 的定义 静态属性 default 构造函数 constructor 方法 request HTTP 方法封装 创建 WxRequest 实例并导出 完整代码&#xff1a; 类 WxRequest 的定义 创建一个 WxRequest 类包含一个静态属性 default 和几个方法&#xff0c;用于处理网络请求。 静态…

【后端开发】JavaEE初阶—Theard类及常见方法—线程的操作(超详解)

前言&#xff1a; &#x1f31f;&#x1f31f;本期讲解多线程的知识哟~~~&#xff0c;希望能帮到屏幕前的你。 &#x1f308;上期博客在这里&#xff1a;【后端开发】JavaEE初阶—线程的理解和编程实现-CSDN博客 &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondl…

计算机毕业设计之:基于深度学习的路面检测系统(源码+部署文档+讲解)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…