局部直方图 算法优化

这是我在写数字图像处理第三章中局部直方图优化的一些体会,最大的体会就是优化计算方法可以极大地加快运算速度

1、优化前

源代码

这是根据数字图像处理p75的公式写的

#例3.10

#局部直方图均衡

import cv2
import numpy as np
import self_def

img = cv2.imread("1.tif",0)

#1截取图像,调试时减小计算时间
cut_m,cut_n = 300,300 #截取的行数和列数
img_cut = np.zeros((cut_m,cut_n))
img_cut = img_cut.astype(np.uint8)
img_cut = img[0:cut_m,0:cut_n]


L = np.max(img_cut)+1  #计算灰度范围
rk = np.arange(L)
m,n = np.shape(img_cut)

#填充
img_fill = np.zeros((m+2,n+2),dtype=int)
img_fill[1:m+1,1:n+1] = img_cut #注意,应该写道m+1
#int_img_fill = img_fill.astype(np.uint8)
img_trans = np.zeros((m,n),dtype=int)
for i in range(m):
    for j in range(n):
        img_temp = np.zeros((3,3),dtype=int)
        img_temp[:,:] = img_fill[i:i+3,j:j+3]

        L_max = np.max(img_temp) + 1  # 计算灰度范围
        L_min = np.min(img_temp)
        rk = np.arange(L_max)
        m_, n_ = np.shape(img_temp)

        # 统计每个灰度级的个数
        nk = np.zeros(L_max)
        for i_ in range(m_):
            for j_ in range(n_):
                nk[img_temp[i_, j_]] += 1

        pk = nk / (m_ * n_)  # 3.3-7

        sk = np.zeros(L_max)
        # 计算变换后的灰度
        for i_ in np.arange(L_min,L_max):
            # 3.3-8
            for j_ in range(i_+1): #注意加一!!!!
                sk[i_] += (L_max - 1) * pk[j_]

        img_trans[i,j] = sk[img_cut[i,j]]



print("end") #用于调试
cv2.imshow("img",img_cut)
cv2.imshow("img_fill",img_trans.astype(np.uint8))

cv2.waitKey(0)
cv2.destroyAllWindows()

结果

 我为了节省时间,只选取了一部分进行处理,尽管这样,仍然花费了大约五分钟

这么慢令我十分不爽,仔细研究发现,在邻域中只有九个灰度,计算时也只需要计算这九个灰度即可,而在我设计的算法中,把[0,L-1]范围内所有的灰度都计算了,这样就增加了很多的计算量,于是进行优化

2、优化后

源代码

#例3.10

#局部直方图均衡

import cv2
import numpy as np
import self_def

img = cv2.imread("1.tif",0)

m,n = np.shape(img)
'''2改进算法后,没必要截取图像
#1截取图像
cut_m,cut_n = 150,150 #截取的行数和列数
img_cut = np.zeros((cut_m,cut_n))
img_cut = img_cut.astype(np.uint8)
img_cut = img[0:cut_m,0:cut_n]'''

m,n = np.shape(img)

#填充
img_fill = np.zeros((m+2,n+2),dtype=int)
img_fill[1:m+1,1:n+1] = img #注意,应该写道m+1
#int_img_fill = img_fill.astype(np.uint8)
img_trans = np.zeros((m,n),dtype=int)
for i in range(m):
    for j in range(n):
        temp = np.zeros((3,3),dtype=int)
        temp[:, :] = img_fill[i:i + 3, j:j + 3]
        huidu_temp = temp.reshape(1,9)
        rk = np.sort(huidu_temp)
        #huidu_temp_number = np.zeros(9,dtype=int)
        rk_unique = np.unique(rk)
        nk = []
        for i_ in rk_unique:
            nk.append(np.sum(rk == i_))  #有问题

        sk = []
        kind_number = np.size(rk_unique)
        for i_ in range(kind_number):
            sum_ = 0
            for j_ in range(i_+1):  #注意这个加一

                sum_ += rk_unique[-1]*nk[j_]/9

            sk.append(int(sum_))

            if rk_unique[i_]==img[i,j]: #顺便也求出邻域中心的灰度的位置
                temp = i_

        img_trans[i, j] = sk[temp]



print("end") #用于调试
cv2.imshow("img",img)
cv2.imshow("img_cut",img_trans.astype(np.uint8))

cv2.waitKey(0)
cv2.destroyAllWindows()

结果

这次运算只花了约8s的时间,可见优化计算方法的重要性

遗憾的是,我将邻域由3,扩展到5,再扩展到9,都没有实现图3.26的结果

 

原文地址:https://www.cnblogs.com/jingxin-gewu/p/13341815.html