六:OpenCV图像变换与增强二(C++/python)

上一篇文章一共介绍了4种图像变换和增强的方法,接下来继续介绍剩下的5种方法,如下:

  1. sqrt
    2.equalizeHist
    3.CLAHE
    4.detailEnhance
    5.illuminationChange

1. 函数 sqrt (将图像进行开方变换)

定义:

void sqrt(InputArray src, OutputArray dst);
def sqrt(src, dst=None)

参数:
src:输入图像
dst:输出图像

作用:将图像进行开方变换,变换之后的数据类型为浮点型或双精度型,如果需要显示变换之后的图像,需要用到convertScaleAbs函数将其转为8位无符号数,如果有必要,还可能进行归一化操作将像素值变换到[0,255]区间。

使用案例

#python code
img=cv2.imread('xxx.jpg')
img_32 = np.float32(img)
sqrtImage = cv2.sqrt(img_32)
plt.figure("sqrtImage")
plt.title("sqrtImage")
plt.imshow(sqrtImage)
plt.show()

#C++ code
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    Mat src = imread("xxxx.png", 0);
    Mat dst;
    Mat convertToMat;
    src.convertTo(convertToMat, CV_32F);
    sqrt(convertToMat, dst);
    convertScaleAbs(dst, dst);
    normalize(dst, dst, 0, 255, NORM_MINMAX);
    namedWindow("src", 0);
    imshow("src", src);
    namedWindow("dst", 0);
    imshow("dst", dst);
    waitKey(0);
    return 0;
}

效果图
opencv-sqrt

根据效果图可以明显的看出对整张图片亮度是有提升的,提升亮度同时图片色彩变得更柔和

2.函数 equalizeHist (直方图均衡化)

定义:

void equalizeHist( InputArray src, OutputArray dst );
def equalizeHist(src, dst=None)

参数:
src:输入图像
dst:输出图像
作用:直方图均衡化,用于增强图像。

使用案例

#python code
img=cv2.imread('demo.jpg')
equalizeHistImage = cv2.equalizeHist(img)
plt.figure("equalizeHistImage")
plt.title("equalizeHistImage")
plt.imshow(equalizeHistImage)
plt.show()

#C++ code
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    Mat src = imread("demo.png", 0);
    Mat dst;
    equalizeHist(src, dst);
    namedWindow("src", 0);
    imshow("src", src);
    namedWindow("dst", 0);
    imshow("dst", dst);
    waitKey(0);
    return 0;
}

效果图

根据效果图展示,equalizeHist对整体图片亮度进行提升,同时对比度也加深。

3.函数 CLAHE (自适应直方图均衡化)

参数:
clipLimit:对比度限制大小(推荐2~5,太大了噪声太多)
tileGridSize :方格大小,将图片按照大小进行分割,针对方格进行白平衡

作用:自适应直方图均衡化,用于增强图像。
使用案例

#python code
#python中需要将不同的通道分离后做自适应白平衡,然后合并图片
img=cv2.imread('xxx.jpg')
B, G, R = cv2.split(img)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(5,5))
clahe_B = clahe.apply(B)
clahe_G = clahe.apply(G)
clahe_R = clahe.apply(R)
CLAHE = cv2.merge((clahe_B, clahe_G, clahe_R))
plt.figure("CLAHE")
plt.title("CLAHE")
plt.imshow(CLAHE)
plt.show()

#C++ code
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    Mat src = imread("xxx.jpg", 0);
    Mat dst;
    cv::Ptr<CLAHE> clahe = cv::createCLAHE();
    clahe->setClipLimit(4);
    clahe->setTilesGridSize(cv::Size(10, 10));
    clahe->apply(src, dst);
    namedWindow("src", 0);
    imshow("src", src);
    namedWindow("dst", 0);
    imshow("dst", dst);
    waitKey(0);
    return 0;
}

效果图

该函数对图片的亮度提升是整体的,提升亮度同时保留了部分细节像素,因此在大多数时候效果表现很不错。

4.函数 detailEnhance (增强特定图像的细节)

定义:

void detailEnhance(InputArray src, OutputArray dst, float sigma_s = 10,float sigma_r = 0.15f);
def detailEnhance(src, dst=None, sigma_s=None, sigma_r=None)

参数:
src:输入图像,通常为三通道图像
dst:输出图像
sigma_s:范围在 0 到 200 之间
sigma_r:范围在 0 到 1 之间

作用:增强特定图像的细节。

#python code
img=cv2.imread('xxx.jpg')
detailEnhanceImage = cv2.detailEnhance(img,None,20,0.8)
plt.figure("detailEnhanceImage")
plt.title("detailEnhanceImage")
plt.imshow(detailEnhanceImage)
 plt.show()

#c++ code
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    Mat src = imread("xxx.jpg", 1);
    Mat dst;
    detailEnhance(src, dst,20,0.8);
    namedWindow("src", 0);
    imshow("src", src);
    namedWindow("dst", 0);
    imshow("dst", dst);
    waitKey(0);
    return 0;
}

效果图

对细节部分的像素有增强作用

5.函数 illuminationChange (消除高光,改善图像的亮度)

定义:
void illuminationChange(InputArray src, InputArray mask, OutputArray dst, float alpha = 0.2f, float beta = 0.4f);
def illuminationChange(src, mask, dst=None, alpha=None, beta=None)

参数:
src:输入图像,通常为三通道图像
mask:掩码,可以传入noArray(),为单通道或三通道图像
dst:输出图像
alpha:范围在 0 到 2 之间 ,数字越大越模糊
beta:范围在 0 到 2 之间

作用:改善图像的亮度。

使用案例

#python code
img=cv2.imread("test.jpg")
img_zero = np.zeros(img.shape, dtype=np.uint8)
img=cv2.illuminationChange(img,mask=img_zero,alpha=0.2,beta=0.4)
cv2.namedWindow("img", cv2.WINDOW_NORMAL)
cv2.imshow("img", img)

cv2.waitKey(0)
cv2.destroyAllWindows()

#C++ code
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    Mat src = imread("test.png", 1);
    Mat dst;
    illuminationChange(src, noArray(), dst, 0.2, 0.4);
    namedWindow("src", 0);
    imshow("src", src);
    namedWindow("dst", 0);
    imshow("dst", dst);
    waitKey(0);
    return 0;
}

效果图
(后续补上)

在改善亮度的的场景中主要是用来消除高光区域