C++基于opencv的视频质量检测--图像清晰度检测
文章目录
- 0.引言
- 1. 原始算法实现
- 2. 优化思路
- 3. 优化后的代码
- 4. 代码详细解读
0.引言
视频质量图像清晰度检测已在C++基于opencv4的视频质量检测中有所介绍,本文将详细介绍其优化版本。
1. 原始算法实现
原始代码:
double sharpnessDetect(const cv::Mat& srcImg) {const int kGaussianSize = 3; // 高斯模糊的核大小cv::Mat grayImg;if (srcImg.channels() != 1) {cv::cvtColor(srcImg, grayImg, cv::COLOR_BGR2GRAY);} else {grayImg = srcImg;}cv::Mat blurredImg;cv::GaussianBlur(grayImg, blurredImg, cv::Size(kGaussianSize, kGaussianSize), 0);uint64_t sumFver = 0;uint64_t sumFhor = 0;uint64_t sumVver = 0;uint64_t sumVhor = 0;double blurFactor = 0.0;for (int r = 0; r < grayImg.rows; ++r) {for (int c = 0; c < grayImg.cols; ++c) {uint64_t diffFver = 0;uint64_t diffFhor = 0;uint64_t diffBver = 0;uint64_t diffBhor = 0;if (r != 0) {diffFver = static_cast<uint64_t>(std::abs(grayImg.at<uchar>(r, c) - grayImg.at<uchar>(r - 1, c)));}if (c != 0) {diffFhor = static_cast<uint64_t>(std::abs(grayImg.at<uchar>(r, c) - grayImg.at<uchar>(r, c - 1)));}if (r != 0) {diffBver = static_cast<uint64_t>(std::abs(blurredImg.at<uchar>(r, c) - blurredImg.at<uchar>(r - 1, c)));}if (c != 0) {diffBhor = static_cast<uint64_t>(std::abs(blurredImg.at<uchar>(r, c) - blurredImg.at<uchar>(r, c - 1)));}uint64_t verDiff = (diffFver > diffBver) ? (diffFver - diffBver) : 0;uint64_t horDiff = (diffFhor > diffBhor) ? (diffFhor - diffBhor) : 0;sumFver += diffFver;sumFhor += diffFhor;sumVver += verDiff;sumVhor += horDiff;}}double bFver = (static_cast<double>(sumFver - sumVver)) / (static_cast<double>(sumFver) + 1.0);double bFhor = (static_cast<double>(sumFhor - sumVhor)) / (static_cast<double>(sumFhor) + 1.0);blurFactor = (bFver > bFhor) ? bFver : bFhor;return 1.0 - blurFactor;
}
以下是原始代码的主要步骤:
- 图像预处理:将输入图像转换为灰度图。
- 高斯模糊:对灰度图像进行高斯模糊处理,得到模糊图像。
- 梯度计算:通过遍历每个像素,计算原始图像和模糊图像在垂直和水平方向上的梯度差异。
- 模糊因子计算:根据梯度差异,计算模糊因子,进而评估图像的清晰度。
存在的问题:
- 效率低下:使用嵌套的
for循环遍历每个像素,手动计算梯度,处理大尺寸图像时效率较低。
2. 优化思路
为了解决上述问题,我们对原始算法进行了以下优化:
- 向量化操作,避免显式循环:利用OpenCV的矩阵运算和函数,对整个图像进行批量处理,提高计算效率。
- 使用Sobel算子计算梯度:Sobel算子是常用的梯度计算方法,能够有效地提取图像的边缘信息。
3. 优化后的代码
以下是优化后的sharpnessDetect函数:
double sharpnessDetect(const cv::Mat& srcImg) {const int kGaussianSize = 3; // 高斯模糊的核大小cv::Mat grayImg;if (srcImg.channels() != 1) {cv::cvtColor(srcImg, grayImg, cv::COLOR_BGR2GRAY);} else {grayImg = srcImg;}// 对灰度图像进行高斯模糊cv::Mat blurredImg;cv::GaussianBlur(grayImg, blurredImg, cv::Size(kGaussianSize, kGaussianSize), 0);// 计算原始图像和模糊图像的梯度cv::Mat gradXOrig, gradYOrig;cv::Mat gradXBlur, gradYBlur;cv::Sobel(grayImg, gradXOrig, CV_64F, 1, 0, 3);cv::Sobel(grayImg, gradYOrig, CV_64F, 0, 1, 3);cv::Sobel(blurredImg, gradXBlur, CV_64F, 1, 0, 3);cv::Sobel(blurredImg, gradYBlur, CV_64F, 0, 1, 3);// 计算梯度的绝对值cv::Mat absGradXOrig = cv::abs(gradXOrig);cv::Mat absGradYOrig = cv::abs(gradYOrig);cv::Mat absGradXBlur = cv::abs(gradXBlur);cv::Mat absGradYBlur = cv::abs(gradYBlur);// 计算梯度差的正值部分cv::Mat diffX = absGradXOrig - absGradXBlur;cv::Mat diffY = absGradYOrig - absGradYBlur;diffX = cv::max(diffX, 0);diffY = cv::max(diffY, 0);// 计算梯度的总和double sumFhor = cv::sum(absGradXOrig)[0];double sumFver = cv::sum(absGradYOrig)[0];// 计算梯度差的总和double sumVhor = cv::sum(diffX)[0];double sumVver = cv::sum(diffY)[0];// 计算模糊因子double bFver = (sumFver - sumVver) / (sumFver + 1e-6);double bFhor = (sumFhor - sumVhor) / (sumFhor + 1e-6);double blurFactor = std::max(bFver, bFhor);// 返回清晰度得分return 1.0 - blurFactor;
}
4. 代码详细解读
流程说明:
- 开始:函数
sharpnessDetect开始执行。 - 检查图像通道数:判断输入图像是否为灰度图。
- 如果不是,转换为灰度图。
- 如果是,跳过转换。
- 高斯模糊:对灰度图像进行高斯模糊处理,得到模糊图像。
- 计算梯度:使用Sobel算子计算原始图像和模糊图像在x和y方向的梯度。
- 计算梯度的绝对值:对梯度矩阵取绝对值。
- 计算梯度差的正值部分:计算原始梯度和模糊梯度之间的差异,保留正值部分。
- 计算梯度的总和:分别计算原始梯度和差异梯度的总和。
- 计算模糊因子:根据梯度总和计算模糊因子。
- 返回结果:根据模糊因子计算清晰度得分,返回结果。
优化细节解读
-
使用Sobel算子计算梯度:
cv::Sobel函数可以高效地计算图像在x和y方向的梯度,避免了手动计算相邻像素差异的繁琐过程。 -
向量化操作:通过
cv::abs、cv::sum等函数,对整个矩阵进行操作,充分利用了底层的优化和并行计算能力。 -
梯度差的正值部分:使用
cv::max函数,将梯度差中的负值置零,保留正值部分,与原始代码的逻辑一致。 -
防止除零错误:在计算模糊因子时,分母加上了一个很小的值
1e-6,防止除以零的情况。 -
数据类型选择:使用
CV_64F(双精度浮点型)确保计算的精度,避免数据溢出和精度损失。
相关文章:
C++基于opencv的视频质量检测--图像清晰度检测
文章目录 0.引言1. 原始算法实现2. 优化思路3. 优化后的代码4. 代码详细解读 0.引言 视频质量图像清晰度检测已在C基于opencv4的视频质量检测中有所介绍,本文将详细介绍其优化版本。 1. 原始算法实现 原始代码: double sharpnessDetect(const cv::Ma…...
力扣11.1
2518. 好分区的数目 给你一个正整数数组 nums 和一个整数 k 。 分区 的定义是:将数组划分成两个有序的 组 ,并满足每个元素 恰好 存在于 某一个 组中。如果分区中每个组的元素和都大于等于 k ,则认为分区是一个好分区。 返回 不同 的好分区…...
打印室预约系统|基于java和小程序的打印室预约系统设计与实现(源码+数据库+文档)
打印室预约系统 目录 基于java和小程序的打印室预约系统设计与实现 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师&#x…...
操作系统-多线程案例
一、单例模式(是一种设计模式) 设计模式有很多种,不同的语法中也有不同的设计模式 单例 单个实例(对象) 某个类,在一个进程中,只应该创建出一个实例,(原则上不该有多个ÿ…...
什么是FUSE用户态文件系统
零. 文件系统 1. 为什么要有文件系统 文件系统是操作系统中管理文件和目录的一种机制。它提供了组织、存储、检索和更新文件的方法,主要如下: 数据组织:文件系统将数据组织成文件和目录,使用户能够更方便地管理和查找文件。每个…...
[每日一练]销售分析(通过数据的0/1转换进行是否存在的查询)
#该题目来源于力扣: 1083. 销售分析 II - 力扣(LeetCode) 题目要求: 表:Product----------------------- | Column Name | Type | ----------------------- | product_id | int | | product_name | varch…...
.NET Core WebApi第7讲:项目的发布与部署
一、理解 前端跟后端拿数据,然后在前端页面中展示,就是我们要完成的事情。 把前端跟后端开发好之后,我们需要落地部署,这个时候就需要一个服务器。 服务器就是一台电脑,只要windows里面有一个叫IIS的管理器。 二、项目…...
【python 将数据写入csv文件】正确方式
data [{username: jack, password: 1234}, ……]# 保存为CSV文件 with open(IP_output.csv, w, newline, encodingutf-8) as file:fieldnames [username, password]writer csv.DictWriter(file, fieldnamesfieldnames, quotingcsv.QUOTE_NONE)writer.writeheader() # 写入列…...
OpenCV4.8 开发实战系列专栏之 10 - 像素值统计
大家好,欢迎大家学习OpenCV4.8 开发实战专栏,长期更新,不断分享源码。 专栏代码全部基于C++ 与Python双语演示,专栏答疑群 请联系微信 OpenCVXueTang_Asst 本文关键知识点:像素值统计 最小(min)最大(max)均值(mean)标准方差(standard deviation)API知识点 最大最小值min…...
pandas计算相关性并画热力图
实现这个功能有很多方法,但是下面的方法还是比较优雅的: cols ["ASSET", "HOUSES", "INCOME", "DEBT", "EDUC"] corr df[cols].corr() corr.style.background_gradient(axisNone)讲解: …...
初始Docker
概述: 容器,作为云原生技术的重要组成部分,与虚拟机一样,均属于虚拟化技术的范畴。然而,容器技术以其独特的优势,在虚拟化领域中脱颖而出。与虚拟机不同,容器能够摆脱操作系统的束缚࿰…...
Redis-概念、安装、基本配置
文章目录 一、Redis及Redis集群概念、分布式系统概念一-1 Redis是什么一-2 什么是分布式系统、分布式缓存一-3 什么是Redis集群、实现Redis集群的方法有哪些、这些跟Redis的sentinel和cluster有什么关系一-4 Redis的库一-5 Redis中的Key与Value是什么、如何进行操作使用它们添加…...
qt QPlainTextEdit详解
QPlainTextEdit是一个功能强大、易于使用的纯文本编辑器/查看器。它使用与QTextEdit相同的技术和概念,但是为纯文本的处理进行了优化,因此更适合处理大型纯文本文档。QPlainTextEdit不提供富文本编辑功能,如字体、颜色、大小等的格式化&#…...
【机器学习】23. 聚类-GMM: Gaussian Mixture Model
1. 定义和假设 定义:probabilistic clustering(model-base) 假设:数据服从正态分布 2. 算法内容 我们假设数据是由k个高斯(正态)分布混合生成的。每个分布有2个参数:μ和σ。 一个分布对应一…...
深度探索C++对象模型
文章目录 前言一、关于对象C对象模型 二、构造函数实例分析 拷贝构造函数程序转化语意学(Program Transformation Semantics)成员初始化列表 三、数据语义学(The Semantics of Data)数据存取多种继承情况讨论仅单一继承加上虚函数多重继承虚拟继承 Pointer to Data Members 四、…...
电脑怎么设置开机密码:保障个人信息安全的第一步
在数字化时代,个人信息的安全至关重要。电脑作为我们日常工作和生活中不可或缺的设备,存储了大量的私人数据和敏感信息。为了防止未经授权的访问,设置开机密码是保护个人隐私和信息安全的基本措施之一。本文将详细介绍如何在不同操作系统下为…...
MybatisPlus入门(六)MybatisPlus-null值处理
一、MybatisPlus-null值处理 1.1)问题引入: 在查询中遇到如下情况,有部分筛选条件没有值,如商品价格有最大值和最小值,商品价格部分时候没有值。 1.2)解决办法: 步骤一:新建查询实…...
红帽认证有必要考吗?这四大人群推荐考取!
红帽认证(Red Hat Certification)作为全球公认的Linux技能认证,对于某些特定人群来说,考取这一认证无疑是一个明智的选择。本文将探讨红帽认证的必要性,并为四类人群提供考取红帽认证的建议。 1. IT专业人士 对于IT专业人士来说࿰…...
基于SSM+微信小程序的社团登录管理系统(社团1)
👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 2、项目技术 3、开发环境 4、功能介绍 1、项目介绍 基于SSM微信小程序的社团登录管理系统实现了管理员及社团、用户。 1、管理员实现了首页、用户管理、社团管理、社团信息管理、社…...
html中cookie如何存储
在HTML中,可以使用JavaScript来创建、读取和删除cookie。以下是创建和读取cookie的基本示例: 创建cookie: function setCookie(name, value, daysToLive) { var cookie name "" encodeURIComponent(value); if (typeof daysToLive …...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
