Smurf
文章50
标签0
分类6
Gray-Level Grouping

Gray-Level Grouping

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

https://blog.csdn.net/linyacool/article/details/74982487

思想概述

本文提出了一个应用在灰度图上的图像对比度增强算法,能够在不需要人工改变算法参数的情况下自动增强图像的对比度,提高显示效果。算法操作的对象集中在灰度直方图上,对比度较低的图像的直方图灰度大多集中在某一区域,算法的目标就是让灰度级更合理的分布在直方图上。振幅小的灰度级应当距离相对较近,振幅大的灰度级则应当相距较远。

算法概述

  • 对于一幅灰度图像,首先得到它的统计直方图 ​, 把强度值非0的灰度级作为初始的组, 初始化 ​​ 和, 分别作为每个组灰度级大小的左边界和右边界。
  • 对于每一次循环:
    • (1)找到所有组中最小的强度值, 记录其下标,在该组左右两边寻找较小的组与其组成一个新的组, 更
    • (2)计算灰度级转换表。计算组间间距N, 首先将两端的灰度级拉伸到该灰度级的端点,然后按照组间
      间距 , 组内间距在 内均匀分布的原则, 计算所有灰度级的转换表
    • (3)将转换函数应用到原始图像上,得到新的直方图,计算像素间的平均距离D。
      循环直到组数为2。寻找最大的像素平均距离D所对应的转换函数 , 并将原始图像转换为最终的对比
      度增强了的图像。

    • ​ 为当前组数,k为灰度阶数

    • 初始值

    • 更新

  • ​​

    • 左/右边界 保存组内序号

    • 初始值

    • 灰度阶数最小的组的
    • transformation fuction
    • 防止当最左侧组只有一个灰度阶数的时候 这一个灰度阶数占太多空间 从而不平均

    • 像素的平均距离

      • 图片中的总像素数
    • 找到最好的​使得最大

代码实现

python版本2.7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# coding=utf-8
import numpy as np
import cv2
import scipy.misc
import os
#import matplotlib.pyplot as plt
import warnings
from argparse import ArgumentParser
warnings.filterwarnings("ignore")
ALPHA = 0.8
M = 256
Threshold = 10

def build_parser():
parser = ArgumentParser()
parser.add_argument('--image',
dest = 'img', help = 'input image',
metavar = 'INPUT_IMAGE.jpg', required = True)
parser.add_argument('--result',
dest='res', help='output image',
metavar='OUTPUT_IMAGE.jpg', required=True)
return parser

def Trans_and_CalcD(H = [],T = []):
M = len(H)
Tar = np.zeros(M+1)
for i in range(M):
if H[i] != 0:
Tar[T[i]] = H[i]
D = 0
for i in range(0,M-1):
for j in range(i+1,M):
D = D + Tar[i] * Tar[j] * (j - i)
return D

def ten(img):
height, width = np.shape(img)
'''
ix = [-1,0,1 iy = [1,2,1
-2,0,2 0,0,0
-1,0,1] -1,-2,-1]
'''
ans = 0
for i in range(1,height-1):
for j in range(1,width-1):
Sx = img[i-1][j+1] + 2 * img[i][j+1] + img[i+1][j+1] - (img[i-1][j-1] + 2 * img[i][j-1] + img[i+1][j-1])
Sy = img[i-1][j-1] + 2 * img[i-1][j] + img[i-1][j+1] - (img[i+1][j-1] + 2 * img[i+1][j] + img[i+1][j+1])
temp = Sx * Sx + Sy * Sy
if temp > Threshold:
ans = ans + temp
return ans

def glg(img):
height,width = np.shape(img)
Npix = height * width
scipy.misc.imsave('original_img.jpg', img)
hist = cv2.calcHist([img], [0], None, [M], [0.0, 255.0])
#show histogram of the original image
'''
bins = np.arange(257)
item = img[:, :]
hist, bins = np.histogram(item, bins)
width = 0.7 * (bins[1] - bins[0])
center = (bins[:-1] + bins[1:]) / 2
plt.bar(center, hist, align='center', width=width)
plt.show()
'''
temp = [0]
temp_gray_level = np.zeros(M)
cnt = 1
for i in range(M):
if hist[i] != 0:
temp.append(hist[i])
temp_gray_level[cnt] = i
cnt = cnt + 1
n = len(temp) - 1
G = [[0] for i in range(n+2)]
gray_level = [[0 for _ in range(n+1)] for __ in range(n+1)]
G[n] = temp
gray_level[n] = temp_gray_level
L = [[0] for i in range(n+2)]
R = [[0] for i in range(n+2)]
for k in range(M):
if hist[k] != 0:
L[n].append(k)
R[n].append(k)
N = np.zeros(n+2).astype(float)
T = [[0 for k in range(M+1)] for i in range(n+2)]
D = np.zeros(n+2)
maxD = 0
Iopt = n - 1

while n >= 3:
#compute Gn-1,Ln-1,Rn-1,i'
a = min(G[n][1:n+1])
ia = G[n].index(a)
left = True
if ia == 1:
b = G[n][ia+1]
left = False
elif ia == n:
b = G[n][ia-1]
else:
if G[n][ia-1] <= G[n][ia+1]:
b = G[n][ia-1]
left = True
else:
b = G[n][ia+1]
left = False
if left:
ii = ia - 1
else:
ii = ia
for i in range(1,ii):
G[n-1].append(G[n][i])
gray_level[n-1][i] = gray_level[n][i]
G[n-1].append(a+b)
gray_level[n-1][ii] = gray_level[n][ii]
for i in range(ii+1,n):
G[n-1].append(G[n][i+1])
gray_level[n-1][i] = gray_level[n][i+1]

for i in range(1,ii+1):
L[n-1].append(L[n][i])
for i in range(ii+1,n):
L[n-1].append(L[n][i+1])

for i in range(1,ii):
R[n-1].append(R[n][i])
for i in range(ii,n):
R[n-1].append(R[n][i+1])

if L[n-1][1] != R[n-1][1]:
N[n-1] = (M - 1)/float(n - 1)
else:
N[n-1] = (M - 1)/float(n - 1 - ALPHA)
for k in range(0,M):
if k <= L[n-1][1]:
T[n - 1][k] = 0
continue
if k >= R[n-1][n-1]:
T[n-1][k] = M - 1
continue
i = 0
for x in range(1,n):
if k >= L[n-1][x] and k < R[n-1][x]:
i = x
if i > 0 and L[n-1][i] != R[n-1][i]:
if L[n-1][1] == R[n-1][1]:
ans = int((i - ALPHA - (R[n - 1][i] - k) / float(R[n - 1][i] - L[n - 1][i])) * float(N[n - 1]) + 1 + 0.5)
T[n - 1][k] = ans
else:
ans = int((i - (R[n - 1][i] - k) / float(R[n - 1][i] - L[n - 1][i])) * float(N[n - 1]) + 1 + 0.5)
T[n - 1][k] = ans
elif i > 0 and L[n-1][i] == R[n-1][i]:
if L[n-1][1] == R[n-1][1]:
T[n - 1][k] =int(((i - ALPHA) * float(N[n - 1])) + 0.5)
else:
T[n - 1][k] =int((i * float(N[n - 1])) + 0.5)
elif k == R[n-1][x]:
i = x
if L[n-1][1] == R[n-1][1]:
T[n - 1][k] = int(((float (i) - ALPHA) * float(N[n - 1])) + 0.5)
else:
T[n - 1][k] = int((i * float(N[n - 1])) + 0.5)
#can be deleted
if i == 0:
T[n-1][k] = T[n-1][k-1]
D[n-1] = Trans_and_CalcD(hist,T[n-1])
if D[n - 1] > maxD:
maxD = D[n - 1]
Iopt = n - 1
#print n - 1, D[n - 1]
n = n - 1
return T[Iopt],D[Iopt]/(float (Npix) * (Npix - 1))

def main():
parser = build_parser()
options = parser.parse_args()
if not os.path.isfile(options.img):
parser.error("Image %s does not exist.)" % options.network)
res = options.res
img = cv2.imread(options.img, cv2.IMREAD_GRAYSCALE)
Trans,PixDist = glg(img)
height, width = np.shape(img)
#reconstruct the enhangced image
image = np.copy(img)
for i in range(0,height):
for j in range(0,width):
image[i][j] = Trans[img[i][j]]
scipy.misc.imsave(res,image)
print "The PixDist is %.1lf" %PixDist
if __name__ == '__main__':
main()
本文作者:Smurf
本文链接:http://example.com/2021/08/15/Image%20processing/%E8%AE%BA%E6%96%87%E9%98%85%E8%AF%BB/%E7%9B%B4%E6%96%B9%E5%9B%BE%E5%9D%87%E8%A1%A1/GLG%E7%AE%97%E6%B3%95/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可