有的圖像有效果,有的效果不好
# -*- coding: utf-8 -*-
import os
import numpy as np
import cv2
import cv2
import numpy as np
import math
def stretchImage(data, s=0.005, bins=2000): # 線性拉伸,去掉最大最小0.5%的像素值,然後線性拉伸至[0,1]
ht = np.histogram(data, bins);
d = np.cumsum(ht[0]) / float(data.size)
lmin = 0;
lmax = bins - 1
while lmin < bins:
if d[lmin] >= s:
break
lmin += 1
while lmax >= 0:
if d[lmax] <= 1 - s:
break
lmax -= 1
return np.clip((data - ht[1][lmin]) / (ht[1][lmax] - ht[1][lmin]), 0, 1)
g_para = {}
def getPara(radius=5): # 根據半徑計算權重參數矩陣
global g_para
m = g_para.get(radius, None)
if m is not None:
return m
size = radius * 2 + 1
m = np.zeros((size, size))
for h in range(-radius, radius + 1):
for w in range(-radius, radius + 1):
if h == 0 and w == 0:
continue
m[radius + h, radius + w] = 1.0 / math.sqrt(h ** 2 + w ** 2)
m /= m.sum()
g_para[radius] = m
return m
def zmIce(I, ratio=4, radius=300): # 常規的ACE實現
para = getPara(radius)
height, width = I.shape
zh, zw = [0] * radius + list(range(height)) + [height - 1] * radius, [0] * radius + list(range(width)) + [width - 1] * radius
Z = I[np.ix_(zh, zw)]
res = np.zeros(I.shape)
for h in range(radius * 2 + 1):
for w in range(radius * 2 + 1):
if para[h][w] == 0:
continue
res += (para[h][w] * np.clip((I - Z[h:h + height, w:w + width]) * ratio, -1, 1))
return res
def zmIceFast(I, ratio, radius): # 單通道ACE快速增強實現
height, width = I.shape[:2]
if min(height, width) <= 2:
return np.zeros(I.shape) + 0.5
Rs = cv2.resize(I, ((width + 1) // 2, (height + 1) // 2))
Rf = zmIceFast(Rs, ratio, radius) # 遞歸調用
Rf = cv2.resize(Rf, (width, height))
Rs = cv2.resize(Rs, (width, height))
return Rf + zmIce(I, ratio, radius) - zmIce(Rs, ratio, radius)
def zmIceColor(I, ratio=4, radius=3): # rgb三通道分別增強,ratio是對比度增強因子,radius是卷積模板半徑
res = np.zeros(I.shape)
for k in range(3):
res[:, :, k] = stretchImage(zmIceFast(I[:, :, k], ratio, radius))
return res
if __name__ == '__main__':
m = zmIceColor(cv2.imread('sRGB/wu1.jpg') / 255.0) * 255
cv2.imwrite('zmIce.jpg', m)
cv2.imshow("img",m)
cv2.waitKey()
//ace 自適應對比度均衡研究
//by jsxyhelu
//感謝 imageshop
#include "stdafx.h"
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
using namespace cv;
//點乘法 elementWiseMultiplication
cv::Mat EWM(cv::Mat m1,cv::Mat m2){
Mat dst=m1.mul(m2);
return dst;
}
//圖像局部對比度增強算法
cv::Mat ACE(cv::Mat src,int C = 4,int n=20,int MaxCG = 5){
Mat meanMask;
Mat varMask;
Mat meanGlobal;
Mat varGlobal;
Mat dst;
Mat tmp;
Mat tmp2;
blur(src.clone(),meanMask,Size(50,50));//meanMask爲局部均值
tmp = src - meanMask;
varMask = EWM(tmp,tmp);
blur(varMask,varMask,Size(50,50)); //varMask爲局部方差
//換算成局部標準差
varMask.convertTo(varMask,CV_32F);
for (int i=0;i<varMask.rows;i++){
for (int j=0;j<varMask.cols;j++){
varMask.at<float>(i,j) = (float)sqrt(varMask.at<float>(i,j));
}
}
meanStdDev(src,meanGlobal,varGlobal); //meanGlobal爲全局均值 varGlobal爲全局標準差
tmp2 = varGlobal/varMask;
for (int i=0;i<tmp2.rows;i++){
for (int j=0;j<tmp2.cols;j++){
if (tmp2.at<float>(i,j)>MaxCG){
tmp2.at<float>(i,j) = MaxCG;
}
}
}
tmp2.convertTo(tmp2,CV_8U);
tmp2 = EWM(tmp2,tmp);
dst = meanMask + tmp2;
imshow("D方法",dst);
dst = meanMask + C*tmp;
imshow("C方法",dst);
return dst;
}
void main()
{
Mat src = imread("plant.bmp",0);
imshow("src",src);
ACE(src);
waitKey();
}