前言
在Android音视频开发中,网上知识点过于零碎,自学起来难度非常大,不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》,结合我自己的工作学习经历,我准备写一个音视频系列blog。本文是音视频系列blog的其中一个, 也是OpenCV的一个入门blog。对应的要学习的内容是:OpenCV分析tfboys十周年演唱会灯牌大战结果(仅供学习,帝国姐妹不要讨伐我啊!!!)。
音视频系列blog
音视频系列blog: 点击此处跳转查看
目录
1 效果图
话不多说,先上效果图!(源代码在文章最后)
演唱会灯牌大战效果图:
分析结果:
2 OpenCV配置
OpenCV是一个开源计算机视觉与图像处理库,同时也提供了丰富的音视频处理功能,它可以用于处理、分析和操作图像、视频以及音频数据。
2.1 下载OpenCV
OpenCV下载地址:opencv.org/releases/ 可以根据自己的电脑的配置下载合适的OpenCV,我下载的是opencv-3.4.2-vc14_vc15.exe,双击该文件进行安装。 我已经默认你们装了vs2017或者其他版本。
2.2 配置OpenCV环境变量
将 OpenCV 配置到 Windows 环境变量中,可以在任何位置轻松访问 OpenCV 库和工具。以下是将 OpenCV 配置为 Windows 环境变量的步骤:
-
找到 OpenCV 安装路径:
- 在安装路径中找到D:\opencv\opencv\build\x64\vc15\bin(vs2015以前的版本以及vs2015找到vc14,我的是vs2017,所以选择vc15)。
-
添加系统环境变量:
- 在 Windows 搜索栏中搜索 "环境变量",并选择 "编辑系统环境变量"。
- 在弹出的 "系统属性" 窗口中,点击 "环境变量" 按钮。
- 在 "环境变量" 窗口的 "系统变量" 部分,找到 "Path" 变量,然后点击 "编辑"。
-
添加 OpenCV 路径:
- 将D:\opencv\opencv\build\x64\vc15\bin添加在"Path" 变量的最后
- 确保每个路径之间使用分号进行分隔。
-
保存更改:
- 点击 "确定" 保存您所做的更改。
- 在打开的窗口中,继续点击 "确定" 以关闭系统属性窗口。
2.3 项目中配置OpenCV
新建 Visual Studio 2017 项目:
打开 Visual Studio 2017,创建一个新的 C++ 项目。
配置项目属性:
- 解决方案资源管理器切换到属性管理器,找到Debug | x64,右键,添加新项目属性表,创建OpenCVDebug.props文件。
- 右键点击OpenCVDebug.props文件,选择"属性"。
- 在"包含目录"项中,添加 OpenCV 的
include
目录的路径,我的是D:\opencv\opencv\build\include
,D:\opencv\opencv\build\include\opencv
,D:\opencv\opencv\build\include\opencv2
。
- 在"库目录"项中,添加 OpenCV 的
lib
目录的路径,我的是D:\opencv\opencv\build\x64\vc15\lib
。
链接 OpenCV 库:
-
在属性对话框中,选择"链接器" -> "输入"。
-
在"附加依赖项"项中,添加以下库文件:
- opencv_worldxxx.lib,这里的 "xxx" 表示 OpenCV 的版本号。例如,如果下载的是 OpenCV 3.4.2,那么对应的库文件就是 opencv_world342d.lib。
修改平台: 将vs2017平台改为x64。
完成以上步骤后,项目应该能够成功地链接和使用 OpenCV 库了。可以在项目中编写和运行 OpenCV 相关的代码。
3 代码分析
先准备一张图片,比如灯牌大战.jpg放在D盘,或者其他地方。
代码整体思路:采用遍历图像的每个像素,根据人眼感知的颜色范围判断像素是否为肉眼可见的颜色,然后计算占比并输出结果。
下面是代码的步骤:
-
导入库:
cpp#include <opencv2/opencv.hpp> #include <iostream>
这部分代码导入了 OpenCV 库和 C++ 的输入输出流库。
-
主函数:
cppint main() { // 读取图像 cv::Mat image = cv::imread("D:\\灯牌大战.jpg"); if (image.empty()) { std::cout << "Error loading image." << std::endl; return -1; }
在主函数中,首先使用 OpenCV 的
imread
函数读取一张图像。如果图像读取失败,将输出错误信息并返回 -1。 -
计算颜色占比:
cpp// 计算每个颜色通道的像素数 int totalPixels = image.rows * image.cols; int visibleBluePixels = 0; int visibleGreenPixels = 0; int visibleRedPixels = 0; // 遍历图像像素,计算肉眼可见的颜色占比 for (int row = 0; row < image.rows; ++row) { for (int col = 0; col < image.cols; ++col) { cv::Vec3b pixel = image.at<cv::Vec3b>(row, col); // 根据人眼感知的颜色范围,判断像素是否为肉眼可见的颜色 if (pixel[2] > 50 && pixel[2] > pixel[1] && pixel[2] > pixel[0]) { // 判断红色 visibleRedPixels++; } else if (pixel[1] > 50 && pixel[1] > pixel[0] && pixel[1] > pixel[2]) { // 判断绿色 visibleGreenPixels++; } else if (pixel[0] > 50 && pixel[0] > pixel[1] && pixel[0] > pixel[2]) { // 判断蓝色 visibleBluePixels++; } } }
这部分代码计算图像中每个颜色通道的像素数,并使用嵌套循环遍历图像的每个像素。对于每个像素,它会根据人眼感知的颜色范围判断是否为肉眼可见的颜色,然后将相应的计数器增加。
-
计算占比并输出结果:
cpp// 计算占比 double visibleBluePercentage = static_cast<double>(visibleBluePixels) / totalPixels * 100; double visibleGreenPercentage = static_cast<double>(visibleGreenPixels) / totalPixels * 100; double visibleRedPercentage = static_cast<double>(visibleRedPixels) / totalPixels * 100; // 打印结果 std::cout << "易烊千玺(红色): " << visibleRedPercentage << "%" << std::endl; std::cout << "王俊凯(蓝色): " << std::fixed << std::setprecision(2) << visibleBluePercentage << "%" << std::endl; std::cout << "王源(绿色): " << visibleGreenPercentage << "%" << std::endl; return 0; }
这部分代码计算肉眼可见的蓝色、绿色和红色的占比,然后输出结果到标准输出。
总结来说,这段代码读取一张图像,遍历图像中的每个像素,根据人眼感知的颜色范围判断像素是否为肉眼可见的颜色,然后计算占比并输出结果。效果图在最上面。
4 源代码
源代码:(欢迎star)
OpenCV分析tfboys十周年演唱会灯牌大战结果