我发现PIL中有ImageOps.autocontrast
的功能,在OpenCV中它对应的功能是什么?
编辑:
我按照pil的文档,以cv2
和numpy
来实现:
import PIL
from PIL import ImageOps, Image
import cv2
import numpy as np
def autocontrast(im, cutoff=0):
channels = []
for i in range(3):
n_bins = 256
hist = cv2.calcHist([im], [i], None, [n_bins], [0, n_bins])
n = np.sum(hist)
cut = cutoff * n // 100
low = np.argwhere(np.cumsum(hist) > cut)
low = low[0]
high = np.argwhere(np.cumsum(hist[::-1]) > cut)
high = n_bins - 1 - high[0]
if high <= low:
table = np.arange(n_bins)
else:
scale = (n_bins - 1) / (high - low)
offset = -low * scale
table = np.arange(n_bins) * scale + offset
table[table < 0] = 0
table[table > n_bins - 1] = n_bins - 1
table = table.astype(np.uint8)
channels.append(table[im[:, :, i]])
out = cv2.merge(channels)
return out
impth = './1_070323.jpg'
im = Image.open(impth)
imcv = cv2.imread(impth)
outcv = autocontrast(imcv, cutoff=10)[:, :, ::-1]
outpil = ImageOps.autocontrast(im, cutoff=10)
print(np.sum(outcv - np.array(outpil)))
现在,我测试了cv2 / numpy和pil方法的速度,发现cv2方法甚至比pil方法还要慢:
impth = './1_070323.jpg'
im = Image.open(impth)
imcv = cv2.imread(impth)
n_test = 100
t1 = time.time()
for i in range(n_test):
outpil = ImageOps.autocontrast(im, cutoff=10)
t2 = time.time()
for i in range(n_test):
outcv = autocontrast(imcv, cutoff=10)
t3 = time.time()
print('pil time: {}'.format(t2 - t1))
print('cv2 time: {}'.format(t3 - t2))
结果是pil需要大约0.8秒,而cv2需要3秒才能运行100次。我已经阅读了pil实现的源代码,其中充满了python for循环。怎么会比cv2 / numpy的实现更快呢?