在python(cv2)中使用OpenCV增加彩色图像对比度的最快方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19363293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 13:33:11  来源:igfitidea点击:

What's the fastest way to increase color image contrast with OpenCV in python (cv2)?

pythonopencvnumpycontrast

提问by Todd Stellanova

I'm using OpenCV to process some images, and one of the first steps I need to perform is increasing the image contrast on a color image. The fastest method I've found so far uses this code (where np is the numpy import) to multiply and add as suggested in the original C-based cv1 docs:

我正在使用 OpenCV 处理一些图像,我需要执行的第一步是增加彩色图像上的图像对比度。到目前为止,我发现的最快的方法是使用此代码(其中 np 是 numpy 导入)按照原始基于 C 的 cv1 文档中的建议进行乘法和加法:

    if (self.array_alpha is None):
        self.array_alpha = np.array([1.25])
        self.array_beta = np.array([-100.0])

    # add a beta value to every pixel 
    cv2.add(new_img, self.array_beta, new_img)                    

    # multiply every pixel value by alpha
    cv2.multiply(new_img, self.array_alpha, new_img)  

Is there a faster way to do this in Python? I've tried using numpy's scalar multiply instead, but the performance is actually worse. I also tried using cv2.convertScaleAbs(the OpenCV docs suggested using convertTo, but cv2 seems to lack an interface to this function) but again the performance was worse in testing.

在 Python 中有没有更快的方法来做到这一点?我尝试过使用 numpy 的标量乘法,但性能实际上更差。我也尝试过使用cv2.convertScaleAbs(OpenCV 文档建议使用convertTo,但 cv2 似乎缺少此函数的接口)但在测试中性能再次变差。

采纳答案by samkhan13

Simple arithmetic in numpy arrays is the fastest, as Abid Rahaman K commented.

正如 Abid Rahaman K 评论的那样,numpy 数组中的简单算术是最快的。

Use this image for example: http://i.imgur.com/Yjo276D.png

例如使用此图像:http: //i.imgur.com/Yjo276D.png

Here is a bit of image processing that resembles brightness/contrast manipulation:

这是一些类似于亮度/对比度处理的图像处理:

'''
Simple and fast image transforms to mimic:
 - brightness
 - contrast
 - erosion 
 - dilation
'''

import cv2
from pylab import array, plot, show, axis, arange, figure, uint8 

# Image data
image = cv2.imread('imgur.png',0) # load as 1-channel 8bit grayscale
cv2.imshow('image',image)
maxIntensity = 255.0 # depends on dtype of image data
x = arange(maxIntensity) 

# Parameters for manipulating image data
phi = 1
theta = 1

# Increase intensity such that
# dark pixels become much brighter, 
# bright pixels become slightly bright
newImage0 = (maxIntensity/phi)*(image/(maxIntensity/theta))**0.5
newImage0 = array(newImage0,dtype=uint8)

cv2.imshow('newImage0',newImage0)
cv2.imwrite('newImage0.jpg',newImage0)

y = (maxIntensity/phi)*(x/(maxIntensity/theta))**0.5

# Decrease intensity such that
# dark pixels become much darker, 
# bright pixels become slightly dark 
newImage1 = (maxIntensity/phi)*(image/(maxIntensity/theta))**2
newImage1 = array(newImage1,dtype=uint8)

cv2.imshow('newImage1',newImage1)

z = (maxIntensity/phi)*(x/(maxIntensity/theta))**2

# Plot the figures
figure()
plot(x,y,'r-') # Increased brightness
plot(x,x,'k:') # Original image
plot(x,z, 'b-') # Decreased brightness
#axis('off')
axis('tight')
show()

# Close figure window and click on other window 
# Then press any keyboard key to close all windows
closeWindow = -1
while closeWindow<0:
    closeWindow = cv2.waitKey(1) 
cv2.destroyAllWindows()

Original image in grayscale:

灰度原始图像:

enter image description here

在此处输入图片说明

Brightened image that appears to be dilated:

看起来被放大的增亮图像:

enter image description here

在此处输入图片说明

Darkened image that appears to be eroded, sharpened, with better contrast:

看起来被侵蚀、锐化、对比度更好的变暗图像:

enter image description here

在此处输入图片说明

How the pixel intensities are being transformed:

像素强度如何被转换:

enter image description here

在此处输入图片说明

If you play with the values of phiand thetayou can get really interesting outcomes. You can also implement this trick for multichannel image data.

如果您使用的价值发挥phi,并theta可以得到非常有趣的结果。您还可以为多通道图像数据实现此技巧。

--- EDIT ---

- - 编辑 - -

have a look at the concepts of 'levels' and 'curves' on this youtube videoshowing image editing in photoshop. The equation for linear transform creates the same amount i.e. 'level' of change on every pixel. If you write an equation which can discriminate between types of pixel (e.g. those which are already of a certain value) then you can change the pixels based on the 'curve' described by that equation.

此 youtube 视频中查看“级别”和“曲线”的概念,该视频显示了在 Photoshop 中的图像编辑。线性变换方程在每个像素上创建相同数量的变化,即“级别”。如果您编写的方程式可以区分像素类型(例如,那些已经具有特定值的像素),那么您可以根据该方程式描述的“曲线”更改像素。

回答by FooBar167

Try this code:

试试这个代码:

import cv2

img = cv2.imread('sunset.jpg', 1)
cv2.imshow("Original image",img)

# CLAHE (Contrast Limited Adaptive Histogram Equalization)
clahe = cv2.createCLAHE(clipLimit=3., tileGridSize=(8,8))

lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)  # convert from BGR to LAB color space
l, a, b = cv2.split(lab)  # split on 3 different channels

l2 = clahe.apply(l)  # apply CLAHE to the L-channel

lab = cv2.merge((l2,a,b))  # merge channels
img2 = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)  # convert from LAB to BGR
cv2.imshow('Increased contrast', img2)
#cv2.imwrite('sunset_modified.jpg', img2)

cv2.waitKey(0)
cv2.destroyAllWindows()

Sunset before: enter image description hereSunset after increased contrast: enter image description here

日落前: 在此处输入图片说明增强对比度后的日落: 在此处输入图片说明

回答by bfris

Use the cv::addWeightedfunction. It's design to work on two images

使用cv::addWeighted函数。设计用于处理两个图像

dst = cv.addWeighted( src1, alpha, src2, beta, gamma[, dst[, dtype]] )

dst = cv.addWeighted( src1, alpha, src2, beta, gamma[, dst[, dtype]] )

But if you use the same image twice AND you set beta to zero, you can get the effect you want

但是如果你使用相同的图像两次并且你将 beta 设置为零,你可以获得你想要的效果

dst = cv.addWeighted( src1, alpha, src1, 0, gamma)

dst = cv.addWeighted(src1, alpha, src1, 0, gamma)

The big advantage to using this function is that you will not have to worry about what happens when values go below 0 or above 255. In numpy, you have to figure out how to do all of the clipping yourself. Using the OpenCV function, it does all of the clipping for you and it's fast.

使用这个函数的最大好处是你不必担心当值低于 0 或高于 255 时会发生什么。在 numpy 中,你必须弄清楚如何自己做所有的剪辑。使用 OpenCV 功能,它会为您完成所有剪辑,而且速度很快。