繁体   English   中英

OpenCV Python或Pillow中的Caxis自动等效项?

[英]Caxis auto equivalent in OpenCV Python or Pillow?

MATLAB具有caxis auto功能,如果对比度低且看上去几乎是黑色的,则可用于查看图像。

在Matlab中,其工作方式如下:

figure;imshow(I);caxis auto

我知道如何在OpenCV Python中调整对比度,例如:

 img = cv2.imread('someimage.jpg',0)
 equ = cv2.equalizeHist(img)

 #Showing image
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

但是,这与caxis auto实现方式caxis auto ,后者会自适应地更改照度。

OpenCV不使用颜色图显示单通道图像。 在Matlab中, caxis设置颜色图限制。 换句话说,如果图像的值在0.5到1.0之间,则可以设置显示的颜色限制,以使0.5呈现 0.0,然后以这种方式缩放。 OpenCV仅按原样显示图像值。

这意味着,如果您希望对值进行不同的缩放,则只需在显示的数组中更改它们即可。

使用OpenCV,您可以使用带有normType=cv2.NORM_MINMAX cv2.normalize()轻松完成此缩放。

img = np.random.rand(500, 500, 3)*0.2
cv2.imshow('Low contrast image', img)
cv2.waitKey()

随机图像

img_scaled = cv2.normalize(img, None, alpha=0.0, beta=1.0, norm_type=cv2.NORM_MINMAX)
cv2.imshow('Scaled colors for display', img_scaled)
cv2.waitKey()

缩放显示

请注意,这适用于灰度图像和彩色图像。


但是,如果您只有灰度图像,则另一个选择是使用Matplotlib显示它们。 MPL将自动将单通道图像缩放到最小/最大显示值。

from matplotlib import pyplot as plt

img = np.random.rand(500, 500)*0.2
plt.imshow(img, cmap='gray')
plt.show()

MPL缩放

请注意,此处包含了cmap='gray'参数,因为单个通道图像的默认颜色图是Viridis ,而不是灰度。 您可以在此处阅读有关Matplotlib颜色图的更多信息。 通常,如果您正在寻找与Matlab类似的语法,那么Matplotlib可以满足您的需求-它最初是为从Matlab进入Python的人们设计的,因此它具有相似的功能和语法。


最后一个选择是仅以numpy手动缩放。 如果您的图片是无符号的int类型,则只需将图片的最低值设置为0,然后相乘以使其最大值成为数据类型的最大值即可。 请注意,当您乘以图像时,图像将被转换为浮点数,因此您需要对其进行重铸。 例如,如果您有uint16图片,则值的范围是0到65535,因此您可以执行以下操作:

img_scaled = img.copy() - np.min(img)
img_scaled = np.uint16(img_scaled*(65535/np.max(img)))

或者,如果您想自动执行此操作,则可以使用np.iinfo()从图像中获取数据类型信息(包括数据类型中的最小值和最大值),以根据需要自动缩放和转换。 这是一个将任何(有符号或无符号)整数或浮点图像标准化的函数:

def normalize_minmax(img):
    """Scales an image into an interval [min, max] with the same datatype.

    If img.dtype is a float type, img is scaled into [0.0, 1.0].
    If img.dtype is an integer type, img is scaled into [dtype.min, dtype.max].
    If img.dtype is some other type, the original image is returned.
    """
    dtype = img.dtype
    if np.issubdtype(dtype, np.integer): # scale to [dtype.min, dtype.max]
        dtype_info = np.iinfo(img.dtype)
        img_scaled = img - np.min(img)
        scale = (dtype_info.max - dtype_info.min) / np.max(img_scaled)
        img_scaled = img_scaled * scale + dtype_info.min
        return np.round(img_scaled).astype(dtype)
    elif np.issubdtype(dtype, np.float):  # scale to [0, 1]
        img_scaled = img - np.min(img)
        img_scaled = img_scaled / np.max(img_scaled)
        return img_scaled.astype(dtype)
    return img

它的工作方式很容易描述。 对于浮动图像,您只需将其移位以使最小值为零,然后除以最大值即可在0和1之间得到它。然后只需将其转换回原始类型即可。 对于整数数据类型,如果要包含有符号整数,则需要花费更多的精力。 在这种情况下,范围也扩展到负数。 您可以通过将最小值移到零来开始相同的操作。 但是然后您需要进行缩放,以使值覆盖数据类型的整个范围(例如(datatype_max-datatype_min)/ max(img))。 因此,现在您的值将跨越[0,datatype_max-datatype_min],因此您需要添加回datatype_min以获得[datatype_min,datatype_max]。 我还对值进行了四舍五入,而不是在转换回原始数据类型之前将其截断。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM