Python/OpenCV中的对比拉伸

2024-09-30 04:32:10 发布

您现在位置:Python中文网/ 问答频道 /正文

在谷歌上搜索直方图均衡化Python或对比度拉伸Python,我被指向了OpenCv中Python文档中的相同链接,它们实际上都与均衡化有关,而不是拉伸(IMO)。

  1. http://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/histogram_equalization/histogram_equalization.html

  2. http://docs.opencv.org/3.2.0/d5/daf/tutorial_py_histogram_equalization.html

阅读文档,它似乎与措辞混淆,因为它将均衡描述为拉伸操作:

What Histogram Equalization does is to stretch out this range.

以及

So you need to stretch this histogram to either ends (as given in below image, from wikipedia) and that is what Histogram Equalization does (in simple words)

我觉得这是错误的,因为维基百科上没有任何地方说直方图均衡化意味着拉伸,阅读其他资料,他们清楚地区分了这两种操作。

  1. http://homepages.inf.ed.ac.uk/rbf/HIPR2/histeq.htm
  2. http://homepages.inf.ed.ac.uk/rbf/HIPR2/stretch.htm

我的问题

  1. OpenCV文档实际上实现了直方图均衡化,但解释得不好吗?

    1. Python中有对比拉伸的实现吗?(OpenCV等?)

Tags: to文档orghttpdocshtml直方图opencv
3条回答

Python/OpenCV可以使用min_max normalization通过cv2.normalize()方法进行对比拉伸。例如:

输入:

enter image description here

#!/bin/python3.7

import cv2
import numpy as np

# read image
img = cv2.imread("zelda3_bm20_cm20.jpg", cv2.IMREAD_COLOR)

# normalize float versions
norm_img1 = cv2.normalize(img, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
norm_img2 = cv2.normalize(img, None, alpha=0, beta=1.2, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)

# scale to uint8
norm_img1 = (255*norm_img1).astype(np.uint8)
norm_img2 = np.clip(norm_img2, 0, 1)
norm_img2 = (255*norm_img2).astype(np.uint8)

# write normalized output images
cv2.imwrite("zelda1_bm20_cm20_normalize1.jpg",norm_img1)
cv2.imwrite("zelda1_bm20_cm20_normalize2.jpg",norm_img2)

# display input and both output images
cv2.imshow('original',img)
cv2.imshow('normalized1',norm_img1)
cv2.imshow('normalized2',norm_img2)
cv2.waitKey(0)
cv2.destroyAllWindows()


标准化1:

enter image description here

标准化2:

enter image description here

你也可以用一个简单的线性方程来做你自己的拉伸,这个方程有2对输入/输出值,形式是y=a*x+B,并求解这两个联立方程。参见How can I make the gradient appearance of one image equal to the other?中所示的拉伸概念

您也可以使用cv2.LUT来进行对比度拉伸,方法是使用np.interp创建自定义表。它们文档的链接分别是thisthis。下面是一个例子。

import cv2
import numpy as np

img = cv2.imread('messi.jpg')
original = img.copy()
xp = [0, 64, 128, 192, 255]
fp = [0, 16, 128, 240, 255]
x = np.arange(256)
table = np.interp(x, xp, fp).astype('uint8')
img = cv2.LUT(img, table)
cv2.imshow("original", original)
cv2.imshow("Output", img)
cv2.waitKey(0)
cv2.destroyAllWindows() 

创建的表

[  0   0   0   0   1   1   1   1   2   2   2   2   3   3   3   3   4   4
   4   4   5   5   5   5   6   6   6   6   7   7   7   7   8   8   8   8
   9   9   9   9  10  10  10  10  11  11  11  11  12  12  12  12  13  13
  13  13  14  14  14  14  15  15  15  15  16  17  19  21  23  24  26  28
  30  31  33  35  37  38  40  42  44  45  47  49  51  52  54  56  58  59
  61  63  65  66  68  70  72  73  75  77  79  80  82  84  86  87  89  91
  93  94  96  98 100 101 103 105 107 108 110 112 114 115 117 119 121 122
 124 126 128 129 131 133 135 136 138 140 142 143 145 147 149 150 152 154
 156 157 159 161 163 164 166 168 170 171 173 175 177 178 180 182 184 185
 187 189 191 192 194 196 198 199 201 203 205 206 208 210 212 213 215 217
 219 220 222 224 226 227 229 231 233 234 236 238 240 240 240 240 240 241
 241 241 241 242 242 242 242 243 243 243 243 244 244 244 244 245 245 245
 245 245 246 246 246 246 247 247 247 247 248 248 248 248 249 249 249 249
 250 250 250 250 250 251 251 251 251 252 252 252 252 253 253 253 253 254
 254 254 254 255]

现在cv2.LUT将用表中的值替换原始图像的值。例如,所有值为1的像素将被0替换,所有值为4的像素将被1替换。

原始图像

Original

对比度拉伸图像

enter image description here

可以根据需要改变xpfp的值来创建自定义表,即使最小和最大像素分别为0和255,与hashcode55提供的答案不同,它也会拉伸对比度。

OpenCV没有任何对比度拉伸功能,google也会得到相同的结果,因为直方图均衡化会水平拉伸直方图,但这只是转换函数的差异。(两种方法都增加了图像的对比度。转换函数将像素强度级别从给定范围传输到所需范围。)

直方图均衡化从给定图像的概率密度函数(PDF)自动导出变换函数(TF),在对比度拉伸中,您可以根据应用程序的要求指定自己的TF。

一个可以做对比拉伸的简单TF是min-max对比拉伸-

((pixel – min) / (max – min))*255.

对每个像素值执行此操作。最小和最大为最小和最大强度。

相关问题 更多 >

    热门问题