图像增强、锐化,利用 Python-OpenCV 实现 4 种方法!

图像增强目的使得模糊图片变得更加清晰、图片模糊的原因是因为像素灰度差值变化不大,如片各区域产生视觉效果似乎都是一样的, 没有较为突出的地方,看起来不清晰的感觉

解决这个问题的最直接简单办法,放大像素灰度值差值、使图像中的细节更加清晰。

目前较为常用的几个方法:伽马变换、线性变换、分段线性变换、直方图均衡化,对于图像对比度增强,都能取得不错的效果!

本文将对每种方法 简单介绍一下,并借助于 Python 、OpenCV 进行代码实现,提前说一下哈,下面处理的图像对象都是单通道灰度图,不是三通道彩色图!

1,线性变换

线性变换的原理是对所有像素值乘上一个扩张因子 factor,像素值大的变得越大,像素值小的变得越小,从而达到图像增强的效果,这里利用 Numpy 的数组进行操作;
O(x,y) = I(x,y)*factor\\ O(x,y)为输出像素值、I(x,y)为输入像素值;O(x,y)为输出像素值、I(x,y)为输入像素值;

需要注意的是,像素值最大为255,因此在数组相乘之后需要进行数值截断操作,最终代码如下:

cdef line_trans_img(img,coffient):
    if len(img.shape) == 3:
        img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    out = 2*img
    #像素截断;;;
    out[out>255] = 255
    out = np.around(out)
    return out

这里 factor 设置为 2 ,变换结果如下,会看到强光处出现失真效果

line.png

这里对排列图片做一下说明,从左到右依次为 原图灰度图、原图灰度直方图、处理之后的灰度图、处理之后的灰度直方图,以下的图片排列方式相同

2,伽马变换

伽马变换对像素值做的是幂次方变换,主要是图像的灰度级发生改变,转换的原理公式为:
O(x,y) = I(x,y)^\gamma\\ O(x,y)、I(x,y)定义与前面一致;
参数 \gamma 的设定 可以参照下面:

Snipaste_2020-05-26_20-18-17.png
  • \gamma>1 时,会减小灰度级较高的地方,增大灰度级较低的地方;
  • \gamma<1 时,会增大灰度级较高的地方,减小灰度级较低的地方;
def gama_transfer(img,power1):
    if len(img.shape) == 3:
         img= cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
    img = 255*np.power(img/255,power1)
    img = np.around(img)
    img[img>255] = 255
    out_img = img.astype(np.uint8)
    return out_img

这里 Gamma 分别取 1.5,0.5,结果如下:

gamma1.5.png

结果来看,相对来说 \gamma >1 对图像增强的结果会更好一点

3,分段线性分割

分段线性分割,提前把图像的灰度级分为几部分,然后对每一部分的像素值做不同的线性变换,像素值基本变换原理:
$$
O(x,y) = \left{
\begin{aligned}
a_1* I(x,y) + b_1 & & 0<I(x,y)<H\
a_2* I(x,y) + b_2 & & H<=I(x,y)<v\
a_3* I(x,y) + b_3 & & v<=I(x,y)\

\end{aligned}
\right.
$$

这里写的代码总感觉效率特别慢(逐像素改变),知道改进方法的小伙伴们望告知:


def seg_augment_img(img,start,c1,end,c2,b2,c3,b3):
    if len(img.shape) == 3:
         img= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    out_img = np.zeros(img.shape)
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            if img[i][j] <start:
                out_img[i][j] = img[i][j]*c1
            elif img[i][j] < end:
                out_img[i][j] = img[i][j] *c2 + b2
            else:
                out_img[i][j] = img[i][j] * c3 +b3

    out_img[out_img>255] = 255
    out = np.around(out_img)
    out = out.astype(np.uint8)
    return out

函数中的参数分别为 50,0.5,150,3.6,-310,0.238,194,结果如下:

seg_line.png

4,直方图均衡化

每个灰度图像都有自己的灰度直方图,均衡化的原理是,先根据灰度直方图计算累加灰度直方图,根据灰度图与累加灰度图的映射关系关联输入图像与输出图图像的映射关系

映射关系原理如下:
O = \frac{\sum_{k=0}^{p}hist_{I}(k)}{h*w}*256 -1\\ h,w表示图像的高和宽\\ O表示输出像素、hist(k)表示图像灰度图中像素为k的个数;\\

因此,这里几个重要部分:1,计算出灰度直方图;2,计算累加灰度直方图;3,根据 1 和 2 得到映射关系,最终输出灰度像素值;

def get_imghist(img):
    # 判断图像是否为三通道;
    if len(img.shape) == 3:
        img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    # 无 Mask,256个bins,取值范围为[0,255]
    hist = cv2.calcHist([img],[0],None,[256],[0,255])
    return hist
    

def cal_equalhist(img):
    if len(img.shape) == 3:
         img= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    h,w = img.shape[:2]
    grathist = get_imghist(img)

    zerosumMoment = np.zeros([256],np.uint32)
    for p in range(256):
        if p ==0:
            zerosumMoment[p] = grathist[0]
        else:
            zerosumMoment[p] = zerosumMoment[p-1] +grathist[p]

    output_q = np.zeros([256],np.uint8)
    cofficient = 256.0/(h*w)
    for p in range(256):
        q = cofficient *float(zerosumMoment[p]) - 1
        if q >= 0:
            output_q[p] = math.floor(q)
        else:
            output_q[p] = 0

    equalhistimage = np.zeros(img.shape,np.uint8)
    for i in range(h):
        for j in range(w):
            equalhistimage[i][j] = output_q[img[i][j]]

    # 第二种方法,opencv 库函数自带一种:
    #equalhistimage = cv2.equalizeHist(img)
    return equalhistimage

结果如下,看起来还是不错的!(这里图片失真是因为灯光的原因)

equalhist.png

小总结

根据以上几个增强方法来看,针对于本案例选取的图像,线性增强方法相对效果并不太好,可能会适用于其它的种类图像,而 Gamma转换 和直方图均衡化取得相对不错的结果

但图像增强、锐化没有最优方法,每种方法都有自己的特点,需要根据自己选择合适的

最后还是要提醒一下感兴趣的小伙伴们,记得跟着敲一下代码,加深一下应用原理!

文章首发于微信公号:Z先生点记 ,若对文章有什么疑问可以在公号后台私信我!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352