2016-09-29 2 views

ответ

1

Взятые из this solution

import numpy as np 
import bisect 

def imadjust(src, tol=1, vin=[0,255], vout=(0,255)): 
    # src : input one-layer image (numpy array) 
    # tol : tolerance, from 0 to 100. 
    # vin : src image bounds 
    # vout : dst image bounds 
    # return : output img 

    dst = src.copy() 
    tol = max(0, min(100, tol)) 

    if tol > 0: 
     # Compute in and out limits 
     # Histogram 
     hist = np.zeros(256, dtype=np.int) 
     for r in range(src.shape[0]): 
      for c in range(src.shape[1]): 
       hist[src[r,c]] += 1 
     # Cumulative histogram 
     cum = hist.copy() 
     for i in range(1, len(hist)): 
      cum[i] = cum[i - 1] + hist[i] 

     # Compute bounds 
     total = src.shape[0] * src.shape[1] 
     low_bound = total * tol/100 
     upp_bound = total * (100 - tol)/100 
     vin[0] = bisect.bisect_left(cum, low_bound) 
     vin[1] = bisect.bisect_left(cum, upp_bound) 

    # Stretching 
    scale = (vout[1] - vout[0])/(vin[1] - vin[0]) 
    for r in range(dst.shape[0]): 
     for c in range(dst.shape[1]): 
      vs = max(src[r,c] - vin[0], 0) 
      vd = min(int(vs * scale + 0.5) + vout[0], vout[1]) 
      dst[r,c] = vd 
    return dst 

, если вы не хотите, чтобы установить ВИН и Vou. Просто используйте cv2.equalizeHist.

@jit 
def hisEqul(img): 
    return cv2.equalizeHist(img) 

@jit 
def hisEqulColor(img): 
    ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB) 
    channels = cv2.split(ycrcb) 
    cv2.equalizeHist(channels[0], channels[0]) 
    cv2.merge(channels, ycrcb) 
    cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR, img) 
    return img 
1

Вы можете найти версию C++ в imadjust здесь: Is there any function equivalent to Matlab's imadjust in OpenCV with C++?

И эту версию питона code из @maslovw очень good.I просто оптимизировать несколько цикл тоже сделать это запустить немного быстрее.

import numpy as np 
import bisect 
from numba import jit 

@jit 
def imadjust(src, tol=1, vin=[0,255], vout=(0,255)): 
    # src : input one-layer image (numpy array) 
    # tol : tolerance, from 0 to 100. 
    # vin : src image bounds 
    # vout : dst image bounds 
    # return : output img 

    assert len(src.shape) == 2 ,'Input image should be 2-dims' 

    tol = max(0, min(100, tol)) 

    if tol > 0: 
     # Compute in and out limits 
     # Histogram 
     hist = np.histogram(src,bins=list(range(256)),range=(0,255))[0] 

     # Cumulative histogram 
     cum = hist.copy() 
     for i in range(1, 256): cum[i] = cum[i - 1] + hist[i] 

     # Compute bounds 
     total = src.shape[0] * src.shape[1] 
     low_bound = total * tol/100 
     upp_bound = total * (100 - tol)/100 
     vin[0] = bisect.bisect_left(cum, low_bound) 
     vin[1] = bisect.bisect_left(cum, upp_bound) 

    # Stretching 
    scale = (vout[1] - vout[0])/(vin[1] - vin[0]) 
    vs = src-vin[0] 
    vs[src<vin[0]]=0 
    vd = vs*scale+0.5 + vout[0] 
    vd[vd>vout[1]] = vout[1] 
    dst = vd 

    return dst 
Смежные вопросы