OpenCV入门例程:裁剪图片、模糊检测、黑屏检测
初级代码游戏的专栏介绍与文章目录-CSDN博客
我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。
这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。
本例程运行环境为CentOS7,64位。代码很简单,三个函数分别裁剪图片、模糊检测、黑屏检测,最后是测试代码。(这个代码应该也是可以在windows上运行的,不确定是不是要经过修改)
需要预先安装OpenCV4。
目录
一、编译参数
二、代码结构(省略的部分在后面)
三、裁剪图片
四、模糊检测
五、黑屏检测
六、测试代码
七、附加说明
一、编译参数
在OpenCV官网下载安装:

注意,本人所用版本没有这么新,不过应该不影响。
程序使用OpenCV需要头文件和库:
头文件包含目录,按照你的安装位置
-I /usr/local/include/opencv4/
链接库,这是全部,程序本身应该不需要链接这么多-lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_calib3d -lopencv_dnn -lopencv_features2d \-lopencv_flann -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching
如果不知道安装到哪里了,用find搜索一下就可以了。
二、代码结构(省略的部分在后面)
#include "opencv2/opencv.hpp"
#include <opencv2/imgproc/types_c.h>
using namespace cv;//图像处理类
class CMyPic
{
private:
public://裁剪图片static bool ClipPic(char const* infile, int x, int y, int width, int heigh, char const* outfile){。。。。。。}//模糊检测static double isImageBlurry(cv::Mat& img){。。。。。}// cast 占比值,阈值为0.85,占比大于阈值认为黑屏static double detect_blackscreen(cv::Mat input_img){。。。。。。}static bool CMyPic_test(){。。。。。。}
};
三个功能三个函数,还有一个是测试。其实四个函数都是独立的,并不需要包装起来。
三、裁剪图片
//裁剪图片static bool ClipPic(char const* infile, int x, int y, int width, int heigh, char const* outfile){Mat pic = imread(infile);if (NULL == pic.data){thelog << "imread失败" << ende;return false;}Rect rect(x, y, width, heigh);Mat newpic = pic(rect);if (NULL == newpic.data){thelog << "剪切失败" << ende;return false;}if (!imwrite(outfile, newpic)){thelog << "imwrite失败" << ende;return false;}return true;}
裁剪图片不在后面的测试代码中,因为这个代码一直在使用,所以也不用测试。
功能很简单,打开输入文件,读取RECT范围到新图片,输出到outfile,文件格式OpenCV会根据文件后缀名自动处理。
用到的几个OpenCV功能:
- imread(文件名) 读取图片文件到Mat结构,根据文件扩展名自动识别格式
- Mat::Mat(RECT) 剪切图片……这也太简单了
- imwrite(文件名,Mat对象) 写文件,根据文件扩展名自动选择输出格式
四、模糊检测
//模糊检测static double isImageBlurry(cv::Mat& img){cv::Mat matImageGray;// converting image's color space (RGB) to grayscalecv::cvtColor(img, matImageGray, CV_BGR2GRAY);cv::Mat dst, abs_dst;cv::Laplacian(matImageGray, dst, CV_16S, 3);cv::convertScaleAbs(dst, abs_dst);cv::Mat tmp_m, tmp_sd;double m = 0, sd = 0;//int threshold = 1000;cv::meanStdDev(dst, tmp_m, tmp_sd);m = tmp_m.at<double>(0, 0);sd = tmp_sd.at<double>(0, 0);return (sd * sd);}
这个就有点复杂了,先转换成灰度,再执行拉普拉斯算子,然后……好吧,其实我也不懂。
用到的几个OpenCV功能:
- cvtColor 转换颜色
- Laplacian 拉普拉斯算子
- convertScaleAbs 取绝对值
- meanStdDev 计算平均值和标准差
五、黑屏检测
// cast 占比值,阈值为0.85,占比大于阈值认为黑屏static double detect_blackscreen(cv::Mat input_img){cv::Mat gray_img;cv::cvtColor(input_img, gray_img, CV_BGR2GRAY);long dark_sum = 0;for (long i = 0; i < gray_img.rows; ++i){for (long j = 0; j < gray_img.cols; ++j){if (gray_img.at<uchar>(i, j) < 20){++dark_sum;}}}return dark_sum / double(gray_img.total());}
先转换成灰度,再计算灰度小于20的点的占比。 返回的是占比,跟阈值比较即可。
这个算法只用到了转换颜色cvtColor。
六、测试代码
static bool CMyPic_test(){struct dirent* drip;DIR* dp;string dirname="目录";if ((dp = opendir(dirname.c_str())) == NULL){thelog << "Error open dir " << dirname << " : " << strerror(errno) << ende;return false;}int ret = 0;while ((drip = readdir(dp)) != NULL){if (strcmp(drip->d_name, ".") == 0 || strcmp(drip->d_name, "..") == 0){continue;}string fullname;fullname = dirname + "/" + drip->d_name;//thelog<<fullname<<endi;bool isdir = IsDir(fullname.c_str());if (isdir){thelog << fullname << "是个目录" << endi;continue;}string ext = ".jpg";//任务文件扩展名int d_name_len = strlen(drip->d_name);if (0 != strcmp(ext.c_str(), drip->d_name + d_name_len - ext.size())){continue;}Mat pic = imread(fullname.c_str());if (NULL == pic.data){thelog << "imread失败" << ende;return false;}//检测模糊double Blurry = isImageBlurry(pic);if (Blurry < 1000){thelog << fullname << "模糊 " << Blurry << endi;}else{//thelog << fullname<< "不模糊" << endi;}//检测黑屏double Black = detect_blackscreen(pic);if (Black > 0.85){thelog << fullname << "黑屏 " << Black << endi;}else{//thelog << fullname << "不黑屏" << endi;}char buf[128];sprintf(buf, ".%ld.%ld.jpg", (long)Blurry, (long)(Black*100));if (!imwrite(((string)drip->d_name + buf).c_str(), pic)){thelog << "imwrite失败" << ende;return false;}}closedir(dp);thelog << dirname << " 处理完毕" << endi;return true;}
这个测试代码读取目录下的所有文件输出判断结果。
七、附加说明
测试代码用到了thelog,功能就是日志输出,替换为cout,ende和endi替换为endl即可。
操作目录的部分需要包含头文件dirent.h。IsDir的实现是这样的:
bool IsDir(char const * strPathName){struct stat statBuf;if (stat(strPathName, &statBuf) == -1){//这里总是返回-1,不知道是什么原因cout << "stat error : " << strPathName << " " << strerror(errno) << endl;return false;}return(statBuf.st_mode & S_IFDIR);}
这个函数似乎有BUG,没搞清怎么回事,这个代码以前是可以用的,也不知道怎么回事,不过不影响测试代码的主要目的。
(这里是文档结束)
相关文章:
OpenCV入门例程:裁剪图片、模糊检测、黑屏检测
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 本例程运行环境为CentOS7&…...
opencv-python库 cv2边界填充resize图片
文章目录 边界填充改变图片大小 边界填充 在OpenCV中,边界填充(Border Padding)是指在图像周围添加额外的像素,以扩展图像的尺寸或满足某些算法(如卷积)的要求。OpenCV提供了cv2.copyMakeBorder()函数来进…...
Java代码基础算法练习-负数个数统计-2024.04.04
任务描述: 从键盘输入任意10个整型数(数值范围-100000~100000),统计其中的负数个数 任务要求: 代码示例: package April_2024;import java.util.Scanner;// 从键盘输入任意10个整型数(数值范围…...
【算法刷题day17】Leetcode:110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和
110.平衡二叉树 文档链接:[代码随想录] 题目链接::110.平衡二叉树 题目: 给定一个二叉树,判断它是否是 平衡二叉树 注意: 判断两棵子树高度差是否大于1 class Solution { public:int result;bool isBalanced(TreeNode…...
C++ | Leetcode C++题解之第10题正则表达式匹配
题目: 题解: class Solution { public:bool isMatch(string s, string p) {int m s.size();int n p.size();auto matches [&](int i, int j) {if (i 0) {return false;}if (p[j - 1] .) {return true;}return s[i - 1] p[j - 1];};vector<…...
职场迷航?MBTI测试为你指明方向,找到最匹配的职业!
MBTI简介 MBTI的全名是Myers-Briggs Type Indicator。它是一种迫选型、自我报告式的性格评估工具,用以衡量和描述人们在获取信息、作出决策、对待生活等方面的心理活动规律和性格类型。 类型指标 美国的凯恩琳布里格斯和她的女儿伊莎贝尔布里格斯迈尔斯研制了迈尔…...
hive 慢sql 查询
hive 慢sql 查询 查找 hive 执行日志存储路径(一般是 hive-audit.log ) 比如:/var/log/Bigdata/audit/hive/hiveserver/hive-audit.log 解析日志 获取 执行时间 执行 OperationId 执行人 UserNameroot 执行sql 数据分隔符为 \001 并写入 hiv…...
Vue - 2( 10000 字 Vue 入门级教程)
一:Vue 1.1 绑定样式 1.1.1 绑定 class 样式 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>绑定样式</title><style>......</style><script type"text/javascript" src&…...
Cisco交换机安全配置
Cisco交换机安全配置 前提 我们以下命令一般都要先进入Config模式 S1> enable S1# conf t S1(config)#端口安全保护 禁用未使用的端口 以关闭fa0/1到fa0/24的端口为例 S1(config)# interface range fa0/1-24 S1(config-if-range)# shutdown缓解MAC地址表攻击 防止CAM…...
LLM大模型可视化-以nano-gpt为例
内容整理自:LLM 可视化 --- LLM Visualization (bbycroft.net)https://bbycroft.net/llm Introduction 介绍 Welcome to the walkthrough of the GPT large language model! Here well explore the model nano-gpt, with a mere 85,000 parameters. 欢迎来到 GPT 大…...
【layui-table】转静态表格时固定表格列处理行高和单元格颜色
处理思路:覆盖layui部分表格样式 行高处理:获取当前行数据单元格的最高高度,将当前行所有数据单元格高度设置为该最高高度 单元格颜色处理:将原生表格转换为layui表格后,因为原生表格的表格结构和生成的layui表格结构…...
如何同时安全高效管理多个谷歌账号?
您的业务活动需要多个 Gmail 帐户吗?出海畅游,Gmail账号是少不了的工具之一,可以关联到Twitter、Facebook、Youtube、Chatgpt等等平台,可以说是海外网络的“万能锁”。但是大家都知道,以上这些平台注册多账号如果产生关…...
使用docker-tc对host容器进行限流
docker-tc是一个github开源项目,项目地址是https://github.com/lukaszlach/docker-tc。 运行docker-tc docker run -d \ --name docker-tc \ --network host \ --cap-add NET_ADMIN \ --restart always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /var…...
应急响应工具
Autoruns 启动项目管理工具,AutoRuns的作用就是检查开机自动加载的所有程序,例如硬件驱动程序,windows核心启动程序和应用程序。它比windows自带的[msconfig.exe]还要强大,通过它还可以看到一些在msconfig里面无法查看到的病毒和…...
PostgreSQL 文章下架 与 热更新和填充可以提升数据库性能
开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,(…...
什么是 内网穿透
内网穿透是一种技术手段,用于在内部网络(如家庭网络或公司网络)中的设备能够被外部网络访问和控制。它允许将位于私有网络中的设备暴露在公共网络(如互联网)上,从而实现远程访问和管理。 内网穿透通常通过…...
RobotFramework测试框架(11)--变量文件
Variable files包含的variables可以用于test data中(即测试用例)中。Variables可以使用Variables section或者从命令行设置。 但是也允许动态创建。 变量文件通常使用模块实现,有两种实现方式。 1、直接从模块中获取变量 变量被指定为模块…...
java八股——常见设计模式
上一篇传送门:点我 有哪些设计模式? 按照模式的应用目标分类,可以分为创建型模式、结构型模式、行为型模式三类。 创建型模式: 对象实例化的模式,创建型模式用于解耦对象的实例化过程。 单例模式:某个类…...
机器学习 - metric评估方法
有一些方法来评估classification model。 Metric name / Evaluation methodDefinitionCodeAccuracyOut of 100 predictions, how many does your model get correct? E.g. 95% accuracy means it gets 95/100 predictions correct.torchmetrics.Accuracy() or sklearn.metric…...
书生·浦语大模型趣味Demo作业( 第二节课)第二期
文章目录 基础作业进阶作业 基础作业 进阶作业 熟悉 huggingface 下载功能,使用 huggingface_hub python 包,下载 InternLM2-Chat-7B 的 config.json 文件到本地(需截图下载过程) 完成 浦语灵笔2 的 图文创作 及 视觉问答 部署&…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
