1. 程式人生 > >OpenCV圖像增強算法實現(直方圖均衡化、拉普拉斯、Log、Gamma)

OpenCV圖像增強算法實現(直方圖均衡化、拉普拉斯、Log、Gamma)

filter 情況下 wait highgui title mod jpg ios converts

OpenCV圖像增強算法實現(直方圖均衡化、拉普拉斯、Log、Gamma)

1. 基於直方圖均衡化的圖像增強

直方圖均衡化是通過調整圖像的灰階分布,使得在0~255灰階上的分布更加均衡,提高了圖像的對比度,達到改善圖像主觀視覺效果的目的。對比度較低的圖像適合使用直方圖均衡化方法來增強圖像細節。 彩色圖像的直方圖均衡化實現:
#include <opencv2/highgui/highgui.hpp>    
#include <opencv2/imgproc/imgproc.hpp>
#include 
<iostream> using namespace cv; int main(int argc, char *argv[]) { Mat image = imread("Test.jpg", 1); if (image.empty()) { std::cout << "打開圖片失敗,請檢查" << std::endl; return -1; } imshow("原圖像", image); Mat imageRGB[3]; split(image, imageRGB);
for (int i = 0; i < 3; i++) { equalizeHist(imageRGB[i], imageRGB[i]); } merge(imageRGB, 3, image); imshow("直方圖均衡化圖像增強效果", image); waitKey(); return 0; }
直方圖均衡化增強前原圖像: 技術分享圖片 直方圖均衡化增強後效果: 技術分享圖片

2. 基於拉普拉斯算子的圖像增強

使用中心為5的8鄰域拉普拉斯算子與圖像卷積可以達到銳化增強圖像的目的,拉普拉斯算子如下圖所示: 技術分享圖片
拉普拉斯算子可以增強局部的圖像對比度:
#include <opencv2/highgui/highgui.hpp>    
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
 
using namespace cv;
 
int main(int argc, char *argv[])
{
    Mat image = imread("Test.jpg", 1);
    if (image.empty())
    {
        std::cout << "打開圖片失敗,請檢查" << std::endl;
        return -1;
    }
    imshow("原圖像", image);
    Mat imageEnhance;
    Mat kernel = (Mat_<float>(3, 3) << 0, -1, 0, 0, 5, 0, 0, -1, 0);
    filter2D(image, imageEnhance, CV_8UC3, kernel);
    imshow("拉普拉斯算子圖像增強效果", imageEnhance);
    waitKey();
    return 0;
}

拉普拉斯算子增強前原圖像:


拉普拉斯算子增強後效果:

3. 基於對數Log變換的圖像增強

對數變換可以將圖像的低灰度值部分擴展,顯示出低灰度部分更多的細節,將其高灰度值部分壓縮,減少高灰度值部分的細節,從而達到強調圖像低灰度部分的目的。變換方法:

對數變換對圖像低灰度部分細節增強的功能過可以從對數圖上直觀理解:

x軸的0.4大約對應了y軸的0.8,即原圖上0~0.4的低灰度部分經過對數運算後擴展到0~0.8的部分,而整個0.4~1的高灰度部分被投影到只有0.8~1的區間,這樣就達到了擴展和增強低灰度部分,壓縮高灰度部分的值的功能。

從上圖還可以看到,對於不同的底數,底數越大,對低灰度部分的擴展就越強,對高灰度部分的壓縮也就越強。

#include <opencv2/highgui/highgui.hpp>    
#include <opencv2/imgproc/imgproc.hpp>
 
using namespace cv;
 
int main(int argc, char *argv[])
{
    Mat image = imread("Test.jpg");
    Mat imageLog(image.size(), CV_32FC3);
    for (int i = 0; i < image.rows; i++)
    {
        for (int j = 0; j < image.cols; j++)
        {
            imageLog.at<Vec3f>(i, j)[0] = log(1 + image.at<Vec3b>(i, j)[0]);
            imageLog.at<Vec3f>(i, j)[1] = log(1 + image.at<Vec3b>(i, j)[1]);
            imageLog.at<Vec3f>(i, j)[2] = log(1 + image.at<Vec3b>(i, j)[2]);
        }
    }
    //歸一化到0~255  
    normalize(imageLog, imageLog, 0, 255, CV_MINMAX);
    //轉換成8bit圖像顯示  
    convertScaleAbs(imageLog, imageLog);
    imshow("Soure", image);
    imshow("after", imageLog);
    waitKey();    
    return 0;
}

對數Log變換增強前原圖像:


對數Log變換增強後效果:


對數變換對於整體對比度偏低並且灰度值偏低的圖像增強效果較好。


4. 基於伽馬變換的圖像增強

伽馬變換主要用於圖像的校正,將灰度過高或者灰度過低的圖片進行修正,增強對比度。變換公式就是對原圖像上每一個像素值做乘積運算:

伽馬變換對圖像的修正作用其實就是通過增強低灰度或高灰度的細節實現的,從伽馬曲線可以直觀理解:

γ值以1為分界,值越小,對圖像低灰度部分的擴展作用就越強,值越大,對圖像高灰度部分的擴展作用就越強,通過不同的γ值,就可以達到增強低灰度或高灰度部分細節的作用。

伽馬變換對於圖像對比度偏低,並且整體亮度值偏高(對於於相機過曝)情況下的圖像增強效果明顯。

#include <opencv2/highgui/highgui.hpp>    
#include <opencv2/imgproc/imgproc.hpp>
 
using namespace cv;
 
int main(int argc, char *argv[])
{
    Mat image = imread("Test.jpg");
    Mat imageGamma(image.size(), CV_32FC3);
    for (int i = 0; i < image.rows; i++)
    {
        for (int j = 0; j < image.cols; j++)
        {
            imageGamma.at<Vec3f>(i, j)[0] = (image.at<Vec3b>(i, j)[0])*(image.at<Vec3b>(i, j)[0])*(image.at<Vec3b>(i, j)[0]);
            imageGamma.at<Vec3f>(i, j)[1] = (image.at<Vec3b>(i, j)[1])*(image.at<Vec3b>(i, j)[1])*(image.at<Vec3b>(i, j)[1]);
            imageGamma.at<Vec3f>(i, j)[2] = (image.at<Vec3b>(i, j)[2])*(image.at<Vec3b>(i, j)[2])*(image.at<Vec3b>(i, j)[2]);
        }
    }
    //歸一化到0~255  
    normalize(imageGamma, imageGamma, 0, 255, CV_MINMAX);
    //轉換成8bit圖像顯示  
    convertScaleAbs(imageGamma, imageGamma);
    imshow("原圖", image);
    imshow("伽馬變換圖像增強效果", imageGamma);
    waitKey();
    return 0;
}
伽馬變換增強前原圖像: 技術分享圖片 伽馬變換增強後效果: 技術分享圖片

OpenCV圖像增強算法實現(直方圖均衡化、拉普拉斯、Log、Gamma)