• 目录分段线性变换对比度拉伸最大最小值拉伸 分段线性变换 优点 形式可以任意复杂 缺点 要求用户输入很多参数 对比度拉伸 光照不足、成像传感器的动态范围偏小、图像获取过程中镜头孔径的设置错误 点(r1,s1...


目录
分段线性变换对比度拉伸最大最小值拉伸

分段线性变换
优点  形式可以任意复杂  缺点  要求用户输入很多参数
对比度拉伸
光照不足、成像传感器的动态范围偏小、图像获取过程中镜头孔径的设置错误
点

(

r

1

,

s

1

)

和

点

(

r

2

,

s

2

)

(r_1, s_1)和点(r_2, s_2)

的位置控制变换函数的形状
图3，令

(

r

1

,

s

1

)

=

(

r

m

i

n

,

0

)

,

(

r

2

,

s

2

)

=

(

r

m

a

x

,

L

−

1

)

(r_1, s_1) = (r_{min}, 0), (r_2, s_2) = (r_{max}, L-1)

图4，令

(

r

1

,

s

1

)

=

(

m

,

0

)

,

(

r

2

,

s

2

)

=

(

m

,

L

−

1

)

，

m

是

平

均

灰

度

级

(r_1, s_1) = (m, 0), (r_2, s_2) = (m, L-1)，m是平均灰度级

def stretch_3(img):
"""
constrast stretch, $(r_1, s_1) = (r_{min}, 0), (r_2, s_2) = (r_{max}, L-1)$
return image stretch
use loop can get right image, but numpy still work, but the return image is more bright(if un normalize, then can get right
result)
"""
img_min = img.min()
img_max = img.max()

#---------------------loop-----------------------------
#     img_dst = np.zeros(img.shape[:2], np.uint8)
#     height, width = img.shape[:2]

#     for h in range(height):
#         for w in range(width):
#             temp = img[h, w]
#             if temp <= img_min:
#                 img_dst[h, w] = 0
#             elif temp >= img_max:
#                 img_dst[h, w] = 255
#             else:
#                 img_dst[h, w] = int(((temp - img_min) / img_max ) * 255)

#-----------------------numpy-----------------------
img_dst = np.piecewise(img, [img <= img_min, img <= img_max], [0, lambda x : (((x - img_min)/ img_max) * 255).astype(np.int)])
return img_dst

def stretch_4(img):
"""
constrast stretch, $(r_1, s_1) = (r_{min}, 0), (r_2, s_2) = (r_{max}, L-1)$
return image stretch
use loop can get right image, but numpy still work, but the return image is more bright(if un normalize, then can get right
result)
"""
img_min = np.mean(img).astype(np.int)
img_max = img.max()

#---------------------loop-----------------------------
#     img_dst = np.zeros(img.shape[:2], np.uint8)
#     height, width = img.shape[:2]

#     for h in range(height):
#         for w in range(width):
#             temp = img[h, w]
#             if temp <= img_min:
#                 img_dst[h, w] = 0
#             elif temp > img_min:
#                 img_dst[h, w] = 255
#             else:
#                 img_dst[h, w] = int(((temp - img_min) / img_max ) * 255)

#-----------------------numpy-----------------------
img_dst = np.piecewise(img, [img >= img_min], [lambda x : 255 if x.any() < img_min else 0])
return img_dst

# 对比度拉伸

# For ploting the stretch curve
x = [0, 96, 182, 255]
y = [0, 30, 220, 255]

# subplot 3
img_subplot3 = stretch_3(img)
img_subplot3 = np.uint8(normalize(img_subplot3) * 255)
# subplot 4
img_subplot4 = stretch_4(img)

plt.figure(figsize=(16, 16))
plt.subplot(2, 2, 1), plt.plot(x, y), plt.title('s=T(r)')
plt.ylabel('Output Value', rotation=90)
plt.xlabel('Input Value',  rotation=0)
plt.subplot(2, 2, 2), plt.imshow(img, cmap='gray', vmin=0, vmax=255), plt.title('Original')
plt.subplot(2, 2, 3), plt.imshow(img_subplot3, cmap='gray', vmin=0, vmax=255), plt.title('Transform 3')
plt.subplot(2, 2, 4), plt.imshow(img_subplot4, cmap='gray', vmin=0, vmax=255), plt.title('Transform 4')
plt.tight_layout()
plt.show()


def SLT(img, x1, x2, y1, y2):
"""
利用opencv, 实现对比度拉伸
"""
lut = np.zeros(256)
for i in range(256):
if i < x1:
lut[i] = (y1/x1)*i
elif i < x2:
lut[i] = ((y2-y1)/(x2-x1))*(i-x1)+y1
else:
lut[i] = ((y2-255.0)/(x2-255.0))*(i-255.0)+255.0
img_output = cv2.LUT(img, lut)
img_output = np.uint8(img_output+0.5)
return img_output

# opencv 对比度拉伸
img_x1 = 100
img_x2 = 160
img_y1 = 50
img_y2 = 255
output_img = SLT(img, img_x1, img_x2, img_y1, img_y2)

plt.figure(figsize=(18, 15))
plt.subplot(1, 2, 1), plt.imshow(img, cmap='gray', vmin=0, vmax=255), plt.title('Original')
plt.subplot(1, 2, 2), plt.imshow(output_img, cmap='gray', vmin=0, vmax=255), plt.title('Transform')
plt.tight_layout()
plt.show()


def sigmoid(x, scale):
"""
simgoid fuction, return ndarray value [0, 1]
param: input x: array like
param: input scale: scale of the sigmoid fuction, if 1, then is original sigmoid fuction, if < 1, then the values between 0, 1
will be less, if scale very low, then become a binary fuction; if > 1, then the values between 0, 1 will be more, if scale
very high then become a y = x
"""
y = 1 / (1 + np.exp(-x / scale))
return y

def sigmoid_transform(image, scale):
"""
use sigmoid function to stretch constract of the image
param: input image: [0, 255] uint8 grayscale image
param: input scale: use scale to change the slope of the stretch curve
return an [0, 255] uint8 gracyscale image
"""
img_temp = image.copy().astype(float)
img_temp = img_temp - 127  # image.max() //2 because the max of input image might not be 255, so use fixed value
img_dst = 1 / (1 + np.exp(- img_temp / scale))
img_dst = np.uint8(normalize(img_dst) * 255.)
return img_dst

# 用Sigmoid函数也可以实现对比度的拉伸，这样就不需要输入过多的参数

# For ploting the stretch curve
x = [0, 96, 182, 255]
y = [0, 30, 220, 255]

# sigmoid function plot
scale = 20
x1 = np.arange(0, 256, 1)
x2 = x1 - x1.max() // 2        # Here shift the 0 to the x center, here is 5, so x1 = [-5,  5]
t_stretch = sigmoid(x2, scale)

# subplot 3 use sigmoid fuction to transform image
img_sigmoid = sigmoid_transform(img, scale)

plt.figure(figsize=(16, 16))
plt.subplot(2, 2, 1), plt.plot(x, y), plt.title('s=T(r)')
plt.ylabel('Output Value', rotation=90)
plt.xlabel('Input Value',  rotation=0)
plt.subplot(2, 2, 2), plt.plot(x1, t_stretch), plt.title('Sigmoid')
plt.ylabel('Output Value', rotation=90)
plt.xlabel('Input Value',  rotation=0)
plt.subplot(2, 2, 3), plt.imshow(img, cmap='gray', vmin=0, vmax=255), plt.title('Original')
plt.subplot(2, 2, 4), plt.imshow(img_sigmoid, cmap='gray', vmin=0, vmax=255), plt.title('Transform 3')
plt.tight_layout()
plt.show()


最大最小值拉伸
def max_min_strech(img):
"""
min max stretch
"""
max1 = np.max(img)
min1 = np.min(img)
output_img = (255.0 * (img-min1)) / (max1 - min1)  # 注意255.0 而不是255 二者算出的结果区别很大
output_img = np.uint8(output_img + 0.5)
return output_img

# 最大最小值拉伸

output_img = max_min_strech(img)

plt.figure(figsize=(20, 10))
plt.subplot(1, 2, 1), plt.imshow(img, cmap='gray'), plt.title('Original')
plt.subplot(1, 2, 2), plt.imshow(output_img, cmap='gray'), plt.title('Transform')
plt.tight_layout()
plt.show()


# 最大最小值拉伸

output_img = max_min_strech(img)

plt.figure(figsize=(16, 10))
plt.subplot(1, 2, 1), plt.imshow(img, cmap='gray'), plt.title('Original')
plt.subplot(1, 2, 2), plt.imshow(output_img, cmap='gray'), plt.title('Transform')
plt.tight_layout()
plt.show()


展开全文
• 对比度拉伸是扩展图像灰度级动态范围的处理。通过在灰度级中确定两个点来控制变换函数的形状。下面是对比度拉伸函数中阈值处理的代码示例，阈值为平均值。 2. 测试结果 图源自skimage 3. 代码 1 def ...

1. 基本原理
对比度拉伸是扩展图像灰度级动态范围的处理。通过在灰度级中确定两个点来控制变换函数的形状。下面是对比度拉伸函数中阈值处理的代码示例，阈值为平均值。
2. 测试结果

图源自skimage
3. 代码

1 def contrast_stretch(input_image):
2     '''
3     对比度拉伸（此实现为阈值处理，阈值为均值）
4     :param input_image: 输入图像
5     :return: 对比图拉伸后的图像
6     '''
7     input_image_cp = np.copy(input_image) # 输入图像的副本
8
9     pixels_value_mean = np.mean(input_image_cp) # 输入图像的平均灰度值
10
11     # 对比图拉伸（注：该实现顺序不能颠倒）
12     input_image_cp[np.where(input_image_cp <= pixels_value_mean)] = 0
13     input_image_cp[np.where(input_image_cp > pixels_value_mean)] = 1
14
15     output_image = input_image_cp
16
17     return output_image

转载于:https://www.cnblogs.com/iwuqing/p/11297259.html
展开全文
• img_adapteq = exposure.equalize_adapthist(img, clip_limit=0.03) 直方图对比度拉伸 # Contrast stretching p2, p98 = np.percentile(img, (2, 98)) img_rescale = exposure.rescale_intensity(img, in_range=(p2...
直方图全局均衡化
from skimage import exposure
# Equalization
img_eq = exposure.equalize_hist(img)

直方图自适应均衡化
# Adaptive Equalization
# 参数2：Clipping limit, normalized between 0 and 1 (higher values give more contrast).

直方图对比度拉伸
# Contrast stretching
p2, p98 = np.percentile(img, (2, 98))
img_rescale = exposure.rescale_intensity(img, in_range=(p2, p98))

实验：直方图全局均衡化、自适应均衡化、对比度拉伸效果对比
"""
======================
Histogram Equalization
======================

This examples enhances an image with low contrast, using a method called
*histogram equalization*, which "spreads out the most frequent intensity
values" in an image. The equalized image has a roughly linear cumulative
distribution function.

While histogram equalization has the advantage that it requires no parameters,
it sometimes yields unnatural looking images.  An alternative method is
*contrast stretching*, where the image is rescaled to include all intensities
that fall within the 2nd and 98th percentiles.

"""

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

from skimage import data, img_as_float
from skimage import exposure

matplotlib.rcParams['font.size'] = 8

def plot_img_and_hist(image, axes, bins=256):
"""Plot an image along with its histogram and cumulative histogram.

"""
image = img_as_float(image)
ax_img, ax_hist = axes
# 共用x轴
ax_cdf = ax_hist.twinx()

# Display image
ax_img.imshow(image, cmap=plt.cm.gray)
ax_img.set_axis_off()

# Display histogram
ax_hist.hist(image.ravel(), bins=bins, histtype='step', color='black')
ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0))
ax_hist.set_xlabel('Pixel intensity')
ax_hist.set_xlim(0, 1)
ax_hist.set_yticks([])

# Display cumulative distribution
img_cdf, bins = exposure.cumulative_distribution(image, bins)
ax_cdf.plot(bins, img_cdf, 'r')
# 设置右侧坐标轴为空
ax_cdf.set_yticks([])

return ax_img, ax_hist, ax_cdf

img = data.moon()

# Contrast stretching
p2, p98 = np.percentile(img, (2, 98))
img_rescale = exposure.rescale_intensity(img, in_range=(p2, p98))

# Equalization
img_eq = exposure.equalize_hist(img)

# 参数2：Clipping limit, normalized between 0 and 1 (higher values give more contrast).

# Display results
fig = plt.figure(figsize=(8, 5))
axes = np.zeros((2, 4), dtype=np.object)
axes[0, 0] = fig.add_subplot(2, 4, 1)
for i in range(1, 4):
axes[0, i] = fig.add_subplot(2, 4, 1+i, sharex=axes[0,0], sharey=axes[0,0])
for i in range(0, 4):
axes[1, i] = fig.add_subplot(2, 4, 5+i)

ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0])
ax_img.set_title('Low contrast image')

y_min, y_max = ax_hist.get_ylim()
ax_hist.set_ylabel('Number of pixels')
# 左侧y轴范围为0到y_max，5个刻度
ax_hist.set_yticks(np.linspace(0, y_max, 5))

ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_rescale, axes[:, 1])
ax_img.set_title('Contrast stretching')

ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_eq, axes[:, 2])
ax_img.set_title('Histogram equalization')

ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_adapteq, axes[:, 3])

ax_cdf.set_ylabel('Fraction of total intensity')
# 右侧y轴范围为0到1,5个刻度
ax_cdf.set_yticks(np.linspace(0, 1, 5))

# prevent overlap of y-axis labels
fig.tight_layout()
plt.show()


展开全文
• ## 图像增强之对比度拉伸

万次阅读 多人点赞 2018-03-24 13:39:59
对比度拉伸是图像增强的一种方法，也属于灰度变换操作。我们看如下图像： 可以看到，这张图片非常灰暗。我们查看下其直方图。 import cv2 import matplotlib.pyplot as plt farina = cv2.imread(...
我们前面提到过图像二值化，图像反转，本质上是对图像的所有像素点的灰度进行操作，属于灰度变换的内容。灰度变换的主要目的是用于图像增强。
而对比度拉伸是图像增强的一种方法，也属于灰度变换操作。我们看如下图像：    可以看到，这张图片非常灰暗。我们查看下其直方图。
import cv2
import matplotlib.pyplot as plt

hist_full = cv2.calcHist([farina], [0], None, [256], [0, 256])

plt.plot(hist_full)
plt.show()
可以看到所有像素的灰度值大部分集中在20-50之间，这使得整个图像很暗淡。也就是说对比度不高。如果我们通过灰度变换，将灰度值拉伸到整个0-255的区间，那么其对比度显然是大幅增强的。可以用如下的公式来将某个像素的灰度值映射到更大的灰度空间：

I(x,y）=I(x,y)−IminImax−Imin(MAX−MIN)+MIN

I

(

x

,

y

）

=

I

(

x

,

y

)

−

I

m

i

n

I

m

a

x

−

I

m

i

n

(

M

A

X

−

M

I

N

)

+

M

I

N

I(x, y）=\frac {I(x,y)-Imin}{Imax-Imin}(MAX-MIN)+MIN

其中Imin，Imax是原始图像的最小灰度值和最大灰度值，MIN和MAX是要拉伸到的灰度空间的灰度最小值和最大值。
Imax = np.max(farina)
Imin = np.min(farina)
MAX = 255
MIN = 0
farina_cs = (farina - Imin) / (Imax - Imin) * (MAX - MIN) + MIN
cv2.imshow("farina_cs", farina_cs.astype("uint8"))
cv2.waitKey()

可以看出，对比度提升了很多。我们再看看其直方图，可以看到已经充满了整个灰度空间。
除了上述方法，对比度拉伸还有其它方法吗？当然是有的。例如直方图位移法（Histogram shifting）。公式如下：，

I(x,y)=I(x,y)+offset

I

(

x

,

y

)

=

I

(

x

,

y

)

+

o

f

f

s

e

t

I(x,y)=I(x,y)+offset
在每个像素位置的灰度值增加一个偏移量offset。注意，这个offset可以是正数，也可以是负数。正的话，整体亮度变亮，负的话，整体亮度变暗。需要注意的是控制offset的值大小，不要越界。

farina_cs = farina + 100
cv2.imshow("farina_offset", farina_cs.astype("uint8"))
cv2.waitKey()
hist_full = cv2.calcHist([farina_cs.astype("uint8")], [0], None, [256], [0, 256])
plt.plot(hist_full)
plt.show()
下面分别是使用直方图位移方法后的图像和其直方图。
可以看出直方图与原始直方图形状一模一样，只是在横轴上有所偏移。这种方法的图像增强效果并没有上一种方法好。
展开全文
• 对图片对比度和亮度的调整一般通过下面公式计算： g(x,y) = a*f(x,y)+b f(x,y)代表源图像x行，y列的像素点的c通道的数值 g(x,y)代表目标图像x行，y列的像素点的c通道的数值a参数（a>0）表示放大的倍数...
• ## OpenCV-Python-(4)-对比度增强

万次阅读 多人点赞 2018-11-13 20:19:54
对比度增强 cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) #图像直方图 cv2.normalize(src[, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]]]) → dst #直方图归一化 ...
• 问题 图像实质上就是一个包含了许多像素点二维数组。 具体计算过程如下： 通过min()函数以及max()函数分别求出处理前原图像的灰度级最小值与最大值； 对原图像进行归一化处理，即用【图像矩阵...以下是 python 代码
• 这段代码可以实现256彩色图像的对比度拉伸
• 对比度：通俗地讲就是亮暗的拉伸对比程度，通常表现了图像画质的清晰程度。对比度的计算公式如下： 2 计算案例 解释： 每个小括号的数据是怎么来的？按四近邻计算，比如第一个小括号：以第一行第一列为中心，...
• 这篇博客将介绍直方图均衡化以及俩种经典的方法：（全局 & 自适应直方图均衡化）； 均衡化作用：1）可以提升图像的对比度；2）使所有图像具有相同的照明条件；
• 声明：本文转自...图像亮度与对比度的调整，是放在skimage包的exposure模块里面 1、gamma调整 原理：I=Ig 对原图像的像素，进行幂运算，得到新的像素值。公式中的g就是gamma值。 如果g
• skimage包的全称是scikit-image SciKit (toolkit...它是由python语言编写的，由scipy 社区开发和维护。skimage包由许多的子模块组成，各个子模块提供不同的功能。主要子模块列表如下： 子模块名称　主要实现功能 io ...
• 拉伸低对比度图像、过度曝光图像，观察图像变换，对图像直方图均衡算法一、在开始之前...定义：灰度拉伸，也称对比度拉伸，是一种简单的线性点运算。 作用：扩展图像的直方图，使其充满整个灰度等级范围内 公式：g(x,y)
• 图像亮度与对比度的调整，是放在skimage包的exposure模块里面 1、gamma调整 原理：I=Ig 对原图像的像素，进行幂运算，得到新的像素值。公式中的g就是gamma值。 如果gamma>1, 新图像比原图像暗 如果gamma<1,新...
• opencv 彩色图像对比度增强
• 定义：灰度拉伸，也称对比度拉伸，是一种简单的线性点运算。作用：扩展图像的 直方图，使其充满整个灰度等级范围内 公式： g(x,y) = 255 / (B - A) * [f(x,y) - A], 其中，A = min[f(x,y)],最小灰度级；B = max[f(x...
• // 对比度拉伸映射 for(int j = 0; j ; j ++) { pDataMat = resultImage.ptr(j); for(int i = 0; i ; i ++) { pDataMat[i] = (pDataMat[i] - pixMin) * 255 / (pixMax - pixMin); } } return ...
• 基于自适应对数映射的局部对比度增强算算法 光照环境不是很好的环境下所拍摄的图片，要么不是太亮，要么就是太暗，不能很好的兼顾亮区和暗区的细节。解决方式有很多种，一种是使用宽动态的sensor，获取一帧长曝光...

...

python 订阅