• 方案介紹
  • 附件下載
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

利用OpenCV根據(jù)圖片識(shí)別環(huán)境的亮度

7小時(shí)前
161
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

更多詳細(xì)資料請(qǐng)聯(lián)系.docx

共1個(gè)文件

一、前言

在當(dāng)代數(shù)字化轉(zhuǎn)型的浪潮中,計(jì)算機(jī)視覺(jué)技術(shù)無(wú)疑占據(jù)了舉足輕重的地位,其應(yīng)用范圍之廣,影響力之深,已成為推動(dòng)社會(huì)進(jìn)步的關(guān)鍵力量之一。而OpenCV,作為計(jì)算機(jī)視覺(jué)領(lǐng)域的佼佼者,憑借其卓越的性能與廣泛的兼容性,為開(kāi)發(fā)者提供了強(qiáng)大的工具集,助力其實(shí)現(xiàn)復(fù)雜視覺(jué)任務(wù)的高效處理。

環(huán)境亮度識(shí)別,實(shí)質(zhì)上是一項(xiàng)要求計(jì)算機(jī)系統(tǒng)能夠精準(zhǔn)分析并量化圖像中光照強(qiáng)度的技術(shù)。要求計(jì)算機(jī)能夠理解并量化人類(lèi)視覺(jué)系統(tǒng)對(duì)光線(xiàn)變化的感知,進(jìn)而做出相應(yīng)的判斷和反應(yīng)。無(wú)論是智能照明系統(tǒng)中的自動(dòng)調(diào)光,還是自動(dòng)駕駛汽車(chē)在復(fù)雜光照條件下的安全導(dǎo)航,亦或是安防監(jiān)控中對(duì)異常光源的即時(shí)警報(bào),這一技術(shù)都扮演著至關(guān)重要的角色。它不僅提高了自動(dòng)化系統(tǒng)的效率和可靠性,還極大地豐富了人機(jī)交互的方式,讓機(jī)器能夠更加“善解人意”。

例如,在智能家居系統(tǒng)中,自動(dòng)調(diào)節(jié)室內(nèi)光線(xiàn)以適應(yīng)不同的活動(dòng)需求或節(jié)能目的;在智能交通系統(tǒng)中,動(dòng)態(tài)調(diào)整道路照明以應(yīng)對(duì)天氣變化和車(chē)流量波動(dòng);在增強(qiáng)現(xiàn)實(shí)領(lǐng)域,實(shí)時(shí)調(diào)整虛擬內(nèi)容的顯示效果以匹配真實(shí)世界的光照條件,這些都是環(huán)境亮度識(shí)別技術(shù)需要用到的地方。。

OpenCV,作為一款開(kāi)源的計(jì)算機(jī)視覺(jué)庫(kù),因其強(qiáng)大的功能和廣泛的適用性,成為了實(shí)現(xiàn)環(huán)境亮度識(shí)別的理想工具。OpenCV不僅提供了豐富的圖像處理函數(shù),還支持多種圖像分析算法,這使得開(kāi)發(fā)者能夠輕松地從圖像中提取亮度信息,并將其轉(zhuǎn)化為可操作的數(shù)據(jù)。通過(guò)加載一張圖片,利用OpenCV的圖像處理能力,可以計(jì)算出圖片中亮度的分布情況,進(jìn)而得到一個(gè)反映環(huán)境亮度水平的百分比值。

本文章介紹如何利用OpenCV加載一張圖片,運(yùn)用OpenCV庫(kù)內(nèi)置的圖像處理技術(shù),識(shí)別并計(jì)算圖片中的亮度百分比。

image-20240715145237647

二、OpenCV開(kāi)發(fā)環(huán)境安裝

【1】OpenCV庫(kù)下載(官網(wǎng))

OpenCV是開(kāi)源的計(jì)算機(jī)視覺(jué)、機(jī)器學(xué)習(xí)軟件庫(kù),其圖片處理的功能非常強(qiáng)大,并且速度很快。 作為目標(biāo)檢測(cè)功能,OpenCV里本身就自帶了很多的模型,比如: 人眼檢測(cè)、鼻子檢測(cè)、嘴巴檢測(cè)、人臉檢測(cè)、人體檢測(cè)、貓臉檢測(cè)等等,下載完OpenCV,就能直接進(jìn)行圖像識(shí)別測(cè)試體驗(yàn),并且OpenCV也可以直接調(diào)用YOLO的模型,精確識(shí)別各種物體,yolo v3 里自帶的模型文件可以精確識(shí)別常見(jiàn)的很多物體: 比如: 狗、汽車(chē)、自行車(chē)、人體、書(shū)本、手機(jī)等等。

OpenCV下載地址:https://opencv.org/releases/page/3/

目前最新的版本是4.3,那么就下載最新的版本。

image-20230906101920240

image-20230906102004369

下載下來(lái)是一個(gè)exe文件,雙擊就可以安裝,實(shí)際就是解壓,可以選擇解壓的路徑,解壓出來(lái)的文件包含源文件、庫(kù)文件一大堆,比較大,可以直接放在一個(gè)固定的目錄,后面程序里直接填路徑來(lái)調(diào)用即可。 這個(gè)下載下來(lái)的庫(kù)文件里只包含了X64的庫(kù),適用于MSVS 64位編譯器。

image-20230906102712398

解壓完成。

image-20230906103311462

解壓后在build目錄下看到有VC14和VC15的目錄。這表示什么含義呢?

OpenCV VC14和VC15的區(qū)別在于它們所使用的編譯器版本不同。VC14使用的是Visual Studio 2015的編譯器,而VC15使用的是Visual Studio 2017的編譯器。這意味著VC15可以利用更先進(jìn)的編譯器技術(shù),從而提高代碼的性能和效率。此外,VC15還支持更多的C++11和C++14特性,使得開(kāi)發(fā)更加方便和靈活。

image-20230906103633870

解釋說(shuō)明:

VC11,Visual Studio 2012編譯器

VC14,Visual Studio 2015編譯器

VC15,Visual Studio 2017編譯器

- VC11構(gòu)建需要安裝Visual Studio 2012 x86或x64的Visual C ++ Redistributable

- VC14構(gòu)建需要安裝Visual Studio 2015 x86或x64的Visual C ++ Redistributable

- VC15構(gòu)建需要安裝Visual Studio 2017 x64或x86的Visual C ++ Redistributable

bin目錄下的運(yùn)行庫(kù)需要拷貝到生成的應(yīng)用程序目錄下。

image-20230906110606683

【2】MinGw編譯器

如果想要使用MinGw編譯器編譯,可以從這里 https://github.com/huihut/OpenCV-MinGW-Build 下載對(duì)應(yīng)的OpenCV庫(kù)進(jìn)行使用。
GitHub的地址在CodeChina有鏡像,可以從這里去下載,速度比較快:gitcode.net/mirrors/hui…
打開(kāi)鏈接后,自己去選擇適合自己編譯器的版本,我的MinGW是730剛好就使用下面這個(gè)版本。

image-20230210093217258

下面分別介紹VS2017 64位編譯器和MinGW 32位編譯器如何引用OpenCV的庫(kù)。

(1)MSVC 64位編譯器–QT的xx.pro工程文件里的寫(xiě)法

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工程文件里的寫(xiě)法

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對(duì)應(yīng)的dll文件拷貝到exe同級(jí)目錄,否則運(yùn)行時(shí)找不到dll會(huì)導(dǎo)致程序異常結(jié)束。 這些dll文件就是在OpenCV的bin目錄下。

OpenCV自帶的模型文件在 C:opencvsourcesdatahaarcascades_cuda 這個(gè)目錄下。

image-20230210093540732

這個(gè)就是人臉檢測(cè)模型文件:

image-20230210093523094

三、實(shí)現(xiàn)代碼

3.1 識(shí)別亮度(C++)

開(kāi)發(fā)環(huán)境:在Windows下安裝一個(gè)VS即可。我當(dāng)前采用的版本是VS2020。

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

// 計(jì)算亮度百分比的函數(shù)
double calculateBrightnessPercentage(Mat image) {
    // 將圖像轉(zhuǎn)換為灰度圖
    Mat grayImage;
    cvtColor(image, grayImage, COLOR_BGR2GRAY);

    // 計(jì)算總像素?cái)?shù)
    int totalPixels = grayImage.rows * grayImage.cols;

    // 計(jì)算亮度較高的像素?cái)?shù)(假設(shè)亮度閾值為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) { // 可根據(jù)需要調(diào)整閾值
                brightPixels++;
            }
        }
    }

    // 計(jì)算亮度百分比
    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 << "無(wú)法打開(kāi)或找到圖像" << endl;
        return -1;
    }

    // 計(jì)算亮度百分比
    double brightnessPercentage = calculateBrightnessPercentage(image);

    // 輸出亮度百分比
    cout << "亮度百分比: " << brightnessPercentage << "%" << endl;

    return 0;
}

(1)頭文件和命名空間:包括必要的OpenCV頭文件 (opencv2/opencv.hpp),使用 cvstd 命名空間以便于調(diào)用。

(2)calculateBrightnessPercentage 函數(shù)

  • 使用 cvtColor 將輸入圖像轉(zhuǎn)換為灰度圖。
  • 計(jì)算圖像中總像素?cái)?shù)。
  • 統(tǒng)計(jì)像素灰度值高于設(shè)定閾值(本例中為200)的像素?cái)?shù)。
  • 計(jì)算亮度百分比,即高亮像素?cái)?shù)占總像素?cái)?shù)的百分比。

(3)main 函數(shù)

  • 使用 imread 從指定路徑加載圖像。
  • 檢查圖像是否成功加載。
  • 調(diào)用 calculateBrightnessPercentage 函數(shù)計(jì)算圖像的亮度百分比。
  • 輸出計(jì)算得到的亮度百分比。

3.2 識(shí)別亮度(Python)

以下是使用Python和OpenCV計(jì)算圖像亮度百分比的代碼示例:

import cv2
import numpy as np

# 計(jì)算亮度百分比的函數(shù)
def calculate_brightness_percentage(image):
    # 轉(zhuǎn)換為灰度圖像
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 計(jì)算總像素?cái)?shù)
    total_pixels = gray_image.shape[0] * gray_image.shape[1]

    # 計(jì)算亮度較高的像素?cái)?shù)(假設(shè)亮度閾值為200)
    bright_pixels = np.sum(gray_image > 200)  # 可根據(jù)需要調(diào)整閾值

    # 計(jì)算亮度百分比
    percentage = (bright_pixels / total_pixels) * 100.0
    return percentage

def main():
    # 加載圖像
    image = cv2.imread('path_to_your_image.jpg')

    if image is None:
        print("無(wú)法打開(kāi)或找到圖像")
        return

    # 計(jì)算亮度百分比
    brightness_percentage = calculate_brightness_percentage(image)

    # 輸出亮度百分比
    print(f"亮度百分比: {brightness_percentage}%")

if __name__ == "__main__":
    main()

(1)函數(shù) calculate_brightness_percentage

  • 使用 cv2.cvtColor 將輸入圖像轉(zhuǎn)換為灰度圖。
  • 計(jì)算圖像中總像素?cái)?shù)。
  • 使用 NumPy 條件判斷 gray_image > 200 來(lái)統(tǒng)計(jì)亮度較高的像素?cái)?shù)(可以根據(jù)需要調(diào)整閾值 200)。
  • 計(jì)算亮度百分比,即高亮像素?cái)?shù)占總像素?cái)?shù)的百分比。

(2)main 函數(shù)

  • 使用 cv2.imread 從指定路徑加載圖像。
  • 檢查圖像是否成功加載。
  • 調(diào)用 calculate_brightness_percentage 函數(shù)計(jì)算圖像的亮度百分比。
  • 輸出計(jì)算得到的亮度百分比。

3.3 顏色分類(lèi)識(shí)別(C++)

開(kāi)發(fā)環(huán)境:在Windows下安裝一個(gè)VS即可。我當(dāng)前采用的版本是VS2020。

下面是使用OpenCV(C++)加載一張圖片,并識(shí)別出黑、白、紅、橙、黃、綠、青、藍(lán)、紫等顏色的占比的完整代碼示例:

#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;

// 計(jì)算顏色比例的函數(shù)
void calculate_color_percentages(Mat image) {
    Mat hsvImage;
    cvtColor(image, hsvImage, COLOR_BGR2HSV);

    // 初始化顏色像素統(tǒng)計(jì)變量
    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]; // 色調(diào)

            // 根據(jù)色調(diào)范圍判斷顏色
            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++;
            }
        }
    }

    // 計(jì)算顏色百分比
    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 << "藍(lán)色百分比: " << percentageBlue << "%" << endl;
    cout << "紫色百分比: " << percentagePurple << "%" << endl;
}

int main() {
    // 加載圖像
    Mat image = imread("path_to_your_image.jpg");

    if (image.empty()) {
        cout << "無(wú)法打開(kāi)或找到圖像" << endl;
        return -1;
    }

    // 計(jì)算顏色比例
    calculate_color_percentages(image);

    return 0;
}

3.4 顏色分類(lèi)識(shí)別(python)

以下是相應(yīng)的Python版本代碼,用于加載圖像并計(jì)算黑、白、紅、橙、黃、綠、青、藍(lán)、紫顏色的占比:

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]), # 藍(lán)色
    'purple': ([131, 43, 46], [160, 255, 255]) # 紫色
}

# 計(jì)算顏色比例的函數(shù)
def calculate_color_percentages(image):
    hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

    # 初始化顏色像素統(tǒng)計(jì)變量
    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)

        # 根據(jù)顏色閾值創(chuàng)建掩碼
        mask = cv2.inRange(hsv_image, lower_np, upper_np)

        # 計(jì)算掩碼中白色像素的數(shù)量
        num_pixels = cv2.countNonZero(mask)

        # 計(jì)算百分比
        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"無(wú)法打開(kāi)或找到圖像:{image_path}")
    else:
        # 計(jì)算顏色比例
        percentages = calculate_color_percentages(image)

        # 輸出顏色百分比
        for color, percentage in percentages.items():
            print(f"{color}百分比: {percentage:.2f}%")

(1)顏色定義和閾值范圍

  • 使用HSV顏色空間來(lái)識(shí)別顏色,定義了各種顏色的HSV閾值范圍。
  • 每個(gè)顏色都有一個(gè)對(duì)應(yīng)的最小和最大HSV值。

(2)calculate_color_percentages 函數(shù)

  • 使用 cv2.cvtColor 將圖像從BGR色彩空間轉(zhuǎn)換為HSV色彩空間。
  • 初始化顏色百分比的字典。
  • 針對(duì)每種顏色的HSV閾值范圍,使用 cv2.inRange 創(chuàng)建顏色掩碼。
  • 使用 cv2.countNonZero 計(jì)算掩碼中非零像素的數(shù)量,即符合顏色條件的像素?cái)?shù)量。
  • 計(jì)算每種顏色在圖像中的百分比。

(3)main 函數(shù)

  • 加載指定路徑的圖像。
  • 檢查圖像是否成功加載。
  • 調(diào)用 calculate_color_percentages 函數(shù)計(jì)算并輸出圖像中各種顏色的百分比。
  • 更多詳細(xì)資料請(qǐng)聯(lián)系.docx
    下載

相關(guān)推薦