利用OpenCV根据图片识别环境的亮度
一、前言
在当代数字化转型的浪潮中,计算机视觉技术无疑占据了举足轻重的地位,其应用范围之广,影响力之深,已成为推动社会进步的关键力量之一。而OpenCV,作为计算机视觉领域的佼佼者,凭借其卓越的性能与广泛的兼容性,为开发者提供了强大的工具集,助力其实现复杂视觉任务的高效处理。
环境亮度识别,实质上是一项要求计算机系统能够精准分析并量化图像中光照强度的技术。要求计算机能够理解并量化人类视觉系统对光线变化的感知,进而做出相应的判断和反应。无论是智能照明系统中的自动调光,还是自动驾驶汽车在复杂光照条件下的安全导航,亦或是安防监控中对异常光源的即时警报,这一技术都扮演着至关重要的角色。它不仅提高了自动化系统的效率和可靠性,还极大地丰富了人机交互的方式,让机器能够更加“善解人意”。
例如,在智能家居系统中,自动调节室内光线以适应不同的活动需求或节能目的;在智能交通系统中,动态调整道路照明以应对天气变化和车流量波动;在增强现实领域,实时调整虚拟内容的显示效果以匹配真实世界的光照条件,这些都是环境亮度识别技术需要用到的地方。。
OpenCV,作为一款开源的计算机视觉库,因其强大的功能和广泛的适用性,成为了实现环境亮度识别的理想工具。OpenCV不仅提供了丰富的图像处理函数,还支持多种图像分析算法,这使得开发者能够轻松地从图像中提取亮度信息,并将其转化为可操作的数据。通过加载一张图片,利用OpenCV的图像处理能力,可以计算出图片中亮度的分布情况,进而得到一个反映环境亮度水平的百分比值。
本文章介绍如何利用OpenCV加载一张图片,运用OpenCV库内置的图像处理技术,识别并计算图片中的亮度百分比。
二、OpenCV开发环境安装
【1】OpenCV库下载(官网)
OpenCV是开源的计算机视觉、机器学习软件库,其图片处理的功能非常强大,并且速度很快。 作为目标检测功能,OpenCV里本身就自带了很多的模型,比如: 人眼检测、鼻子检测、嘴巴检测、人脸检测、人体检测、猫脸检测等等,下载完OpenCV,就能直接进行图像识别测试体验,并且OpenCV也可以直接调用YOLO的模型,精确识别各种物体,yolo v3 里自带的模型文件可以精确识别常见的很多物体: 比如: 狗、汽车、自行车、人体、书本、手机等等。
OpenCV下载地址:https://opencv.org/releases/page/3/
目前最新的版本是4.3,那么就下载最新的版本。
下载下来是一个exe文件,双击就可以安装,实际就是解压,可以选择解压的路径,解压出来的文件包含源文件、库文件一大堆,比较大,可以直接放在一个固定的目录,后面程序里直接填路径来调用即可。 这个下载下来的库文件里只包含了X64的库,适用于MSVS 64位编译器。
解压完成。
解压后在build目录下看到有VC14和VC15的目录。这表示什么含义呢?
OpenCV VC14和VC15的区别在于它们所使用的编译器版本不同。VC14使用的是Visual Studio 2015的编译器,而VC15使用的是Visual Studio 2017的编译器。这意味着VC15可以利用更先进的编译器技术,从而提高代码的性能和效率。此外,VC15还支持更多的C++11和C++14特性,使得开发更加方便和灵活。
解释说明:
VC11,Visual Studio 2012编译器
VC14,Visual Studio 2015编译器
VC15,Visual Studio 2017编译器
- VC11构建需要安装Visual Studio 2012 x86或x64的Visual C ++ Redistributable
- VC14构建需要安装Visual Studio 2015 x86或x64的Visual C ++ Redistributable
- VC15构建需要安装Visual Studio 2017 x64或x86的Visual C ++ Redistributable
在bin
目录下的运行库需要拷贝到生成的应用程序目录下。
【2】MinGw编译器
如果想要使用MinGw编译器编译,可以从这里 https://github.com/huihut/OpenCV-MinGW-Build 下载对应的OpenCV库进行使用。
GitHub的地址在CodeChina有镜像,可以从这里去下载,速度比较快:gitcode.net/mirrors/hui…
打开链接后,自己去选择适合自己编译器的版本,我的MinGW是730刚好就使用下面这个版本。
下面分别介绍VS2017 64位编译器和MinGW 32位编译器如何引用OpenCV的库。
(1)MSVC 64位编译器–QT的xx.pro工程文件里的写法
INCLUDEPATH += C:/opencv/build/include\
INCLUDEPATH += C:/opencv/build/include/opencv\
INCLUDEPATH += C:/opencv/build/include/opencv2
LIBS += -LC:/opencv/build/x64/vc14/lib\
-lopencv_world347d
LIBS += -LC:/opencv/build/x64/vc14/lib\
-lopencv_world347
(2)MinGW 32位编译器–QT的xx.pro工程文件里的写法
INCLUDEPATH+=C:/OpenCV-MinGW-Build-OpenCV-3.4.7/include \
C:/OpenCV-MinGW-Build-OpenCV-3.4.7/include/opencv \
C:/OpenCV-MinGW-Build-OpenCV-3.4.7/include/opencv2
LIBS+=C:/OpenCV-MinGW-Build-OpenCV-3.4.7/x86/mingw/bin/libopencv_*.dll
工程编程成功之后,需要将OpenCV对应的dll文件拷贝到exe同级目录,否则运行时找不到dll会导致程序异常结束。 这些dll文件就是在OpenCV的bin目录下。
OpenCV自带的模型文件在 C:\opencv\sources\data\haarcascades_cuda
这个目录下。
这个就是人脸检测模型文件:
三、实现代码
3.1 识别亮度(C++)
开发环境:在Windows下安装一个VS即可。我当前采用的版本是VS2020。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
// 计算亮度百分比的函数
double calculateBrightnessPercentage(Mat image) {
// 将图像转换为灰度图
Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
// 计算总像素数
int totalPixels = grayImage.rows * grayImage.cols;
// 计算亮度较高的像素数(假设亮度阈值为200)
int brightPixels = 0;
for (int i = 0; i < grayImage.rows; ++i) {
for (int j = 0; j < grayImage.cols; ++j) {
if (grayImage.at<uchar>(i, j) > 200) { // 可根据需要调整阈值
brightPixels++;
}
}
}
// 计算亮度百分比
double percentage = (static_cast<double>(brightPixels) / totalPixels) * 100.0;
return percentage;
}
int main() {
// 加载图像
Mat image = imread("path_to_your_image.jpg");
if (image.empty()) {
cout << "无法打开或找到图像" << endl;
return -1;
}
// 计算亮度百分比
double brightnessPercentage = calculateBrightnessPercentage(image);
// 输出亮度百分比
cout << "亮度百分比: " << brightnessPercentage << "%" << endl;
return 0;
}
(1)头文件和命名空间:包括必要的OpenCV头文件 (opencv2/opencv.hpp
),使用 cv
和 std
命名空间以便于调用。
(2)calculateBrightnessPercentage
函数:
- 使用
cvtColor
将输入图像转换为灰度图。 - 计算图像中总像素数。
- 统计像素灰度值高于设定阈值(本例中为200)的像素数。
- 计算亮度百分比,即高亮像素数占总像素数的百分比。
(3)main
函数:
- 使用
imread
从指定路径加载图像。 - 检查图像是否成功加载。
- 调用
calculateBrightnessPercentage
函数计算图像的亮度百分比。 - 输出计算得到的亮度百分比。
3.2 识别亮度(Python)
以下是使用Python和OpenCV计算图像亮度百分比的代码示例:
import cv2
import numpy as np
# 计算亮度百分比的函数
def calculate_brightness_percentage(image):
# 转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 计算总像素数
total_pixels = gray_image.shape[0] * gray_image.shape[1]
# 计算亮度较高的像素数(假设亮度阈值为200)
bright_pixels = np.sum(gray_image > 200) # 可根据需要调整阈值
# 计算亮度百分比
percentage = (bright_pixels / total_pixels) * 100.0
return percentage
def main():
# 加载图像
image = cv2.imread('path_to_your_image.jpg')
if image is None:
print("无法打开或找到图像")
return
# 计算亮度百分比
brightness_percentage = calculate_brightness_percentage(image)
# 输出亮度百分比
print(f"亮度百分比: {brightness_percentage}%")
if __name__ == "__main__":
main()
(1)函数 calculate_brightness_percentage
:
- 使用
cv2.cvtColor
将输入图像转换为灰度图。 - 计算图像中总像素数。
- 使用 NumPy 条件判断
gray_image > 200
来统计亮度较高的像素数(可以根据需要调整阈值200
)。 - 计算亮度百分比,即高亮像素数占总像素数的百分比。
(2)main
函数:
- 使用
cv2.imread
从指定路径加载图像。 - 检查图像是否成功加载。
- 调用
calculate_brightness_percentage
函数计算图像的亮度百分比。 - 输出计算得到的亮度百分比。
3.3 颜色分类识别(C++)
开发环境:在Windows下安装一个VS即可。我当前采用的版本是VS2020。
下面是使用OpenCV(C++)加载一张图片,并识别出黑、白、红、橙、黄、绿、青、蓝、紫等颜色的占比的完整代码示例:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
// 定义颜色的阈值范围(HSV颜色空间)
const int MIN_H_RED = 0;
const int MAX_H_RED = 10;
const int MIN_H_ORANGE = 11;
const int MAX_H_ORANGE = 25;
const int MIN_H_YELLOW = 26;
const int MAX_H_YELLOW = 34;
const int MIN_H_GREEN = 35;
const int MAX_H_GREEN = 85;
const int MIN_H_CYAN = 86;
const int MAX_H_CYAN = 105;
const int MIN_H_BLUE = 106;
const int MAX_H_BLUE = 130;
const int MIN_H_PURPLE = 131;
const int MAX_H_PURPLE = 160;
// 计算颜色比例的函数
void calculate_color_percentages(Mat image) {
Mat hsvImage;
cvtColor(image, hsvImage, COLOR_BGR2HSV);
// 初始化颜色像素统计变量
int totalPixels = hsvImage.rows * hsvImage.cols;
int blackPixels = 0, whitePixels = 0;
int redPixels = 0, orangePixels = 0, yellowPixels = 0;
int greenPixels = 0, cyanPixels = 0, bluePixels = 0, purplePixels = 0;
// 遍历图像像素
for (int i = 0; i < hsvImage.rows; ++i) {
for (int j = 0; j < hsvImage.cols; ++j) {
Vec3b pixel = hsvImage.at<Vec3b>(i, j);
int hue = pixel[0]; // 色调
// 根据色调范围判断颜色
if (hue >= MIN_H_RED && hue <= MAX_H_RED) {
redPixels++;
} else if (hue >= MIN_H_ORANGE && hue <= MAX_H_ORANGE) {
orangePixels++;
} else if (hue >= MIN_H_YELLOW && hue <= MAX_H_YELLOW) {
yellowPixels++;
} else if (hue >= MIN_H_GREEN && hue <= MAX_H_GREEN) {
greenPixels++;
} else if (hue >= MIN_H_CYAN && hue <= MAX_H_CYAN) {
cyanPixels++;
} else if (hue >= MIN_H_BLUE && hue <= MAX_H_BLUE) {
bluePixels++;
} else if ((hue >= 0 && hue < MIN_H_RED) || (hue > MAX_H_PURPLE && hue <= 179)) {
purplePixels++;
}
}
}
// 计算颜色百分比
double percentageBlack = (static_cast<double>(blackPixels) / totalPixels) * 100.0;
double percentageWhite = (static_cast<double>(whitePixels) / totalPixels) * 100.0;
double percentageRed = (static_cast<double>(redPixels) / totalPixels) * 100.0;
double percentageOrange = (static_cast<double>(orangePixels) / totalPixels) * 100.0;
double percentageYellow = (static_cast<double>(yellowPixels) / totalPixels) * 100.0;
double percentageGreen = (static_cast<double>(greenPixels) / totalPixels) * 100.0;
double percentageCyan = (static_cast<double>(cyanPixels) / totalPixels) * 100.0;
double percentageBlue = (static_cast<double>(bluePixels) / totalPixels) * 100.0;
double percentagePurple = (static_cast<double>(purplePixels) / totalPixels) * 100.0;
// 输出颜色百分比
cout << "黑色百分比: " << percentageBlack << "%" << endl;
cout << "白色百分比: " << percentageWhite << "%" << endl;
cout << "红色百分比: " << percentageRed << "%" << endl;
cout << "橙色百分比: " << percentageOrange << "%" << endl;
cout << "黄色百分比: " << percentageYellow << "%" << endl;
cout << "绿色百分比: " << percentageGreen << "%" << endl;
cout << "青色百分比: " << percentageCyan << "%" << endl;
cout << "蓝色百分比: " << percentageBlue << "%" << endl;
cout << "紫色百分比: " << percentagePurple << "%" << endl;
}
int main() {
// 加载图像
Mat image = imread("path_to_your_image.jpg");
if (image.empty()) {
cout << "无法打开或找到图像" << endl;
return -1;
}
// 计算颜色比例
calculate_color_percentages(image);
return 0;
}
3.4 颜色分类识别(python)
以下是相应的Python版本代码,用于加载图像并计算黑、白、红、橙、黄、绿、青、蓝、紫颜色的占比:
import cv2
import numpy as np
# 定义颜色的阈值范围(HSV颜色空间)
COLOR_THRESHOLDS = {
'black': ([0, 0, 0], [180, 255, 30]), # 黑色
'white': ([0, 0, 231], [180, 18, 255]), # 白色
'red': ([0, 43, 46], [10, 255, 255]), # 红色
'orange': ([11, 43, 46], [25, 255, 255]), # 橙色
'yellow': ([26, 43, 46], [34, 255, 255]), # 黄色
'green': ([35, 43, 46], [85, 255, 255]), # 绿色
'cyan': ([86, 43, 46], [105, 255, 255]), # 青色
'blue': ([106, 43, 46], [130, 255, 255]), # 蓝色
'purple': ([131, 43, 46], [160, 255, 255]) # 紫色
}
# 计算颜色比例的函数
def calculate_color_percentages(image):
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# 初始化颜色像素统计变量
total_pixels = hsv_image.shape[0] * hsv_image.shape[1]
color_percentages = {}
# 遍历颜色阈值范围
for color_name, (lower, upper) in COLOR_THRESHOLDS.items():
lower_np = np.array(lower, dtype=np.uint8)
upper_np = np.array(upper, dtype=np.uint8)
# 根据颜色阈值创建掩码
mask = cv2.inRange(hsv_image, lower_np, upper_np)
# 计算掩码中白色像素的数量
num_pixels = cv2.countNonZero(mask)
# 计算百分比
percentage = (num_pixels / total_pixels) * 100.0
color_percentages[color_name] = percentage
return color_percentages
if __name__ == "__main__":
# 加载图像
image_path = 'path_to_your_image.jpg'
image = cv2.imread(image_path)
if image is None:
print(f"无法打开或找到图像:{image_path}")
else:
# 计算颜色比例
percentages = calculate_color_percentages(image)
# 输出颜色百分比
for color, percentage in percentages.items():
print(f"{color}百分比: {percentage:.2f}%")
(1)颜色定义和阈值范围:
- 使用HSV颜色空间来识别颜色,定义了各种颜色的HSV阈值范围。
- 每个颜色都有一个对应的最小和最大HSV值。
(2)calculate_color_percentages
函数:
- 使用
cv2.cvtColor
将图像从BGR色彩空间转换为HSV色彩空间。 - 初始化颜色百分比的字典。
- 针对每种颜色的HSV阈值范围,使用
cv2.inRange
创建颜色掩码。 - 使用
cv2.countNonZero
计算掩码中非零像素的数量,即符合颜色条件的像素数量。 - 计算每种颜色在图像中的百分比。
(3)main
函数:
- 加载指定路径的图像。
- 检查图像是否成功加载。
- 调用
calculate_color_percentages
函数计算并输出图像中各种颜色的百分比。