ace 圖像增強

有的圖像有效果,有的效果不好

# -*- 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();
}

 

https://zhuanlan.zhihu.com/p/57666772

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章