zoukankan      html  css  js  c++  java
  • 图像分析之图像锐化

    本文叙述了几种实现图像锐化的方式,包括拉普拉斯滤波,加权均值滤波,形态学梯度和顶帽底帽变换。本文的特色在于,大致证明了这几种方式可以实现图像锐化的原因。

    更新记录

    本文持续更新!如文中有错误,或你对本文有疑问或建议,欢迎留言或发邮件至quarrying#qq.com!

    2016年01月08日,发布博文。

    2016年04月28日,更新博文。

    参考

    J.S. Lee, Digital image enhancement and noise filtering by use of local statistics, IEEE Transactions on Pattern Analysis and Machine Intelligence, 2(2):165-168, 1980.

    https://en.wikipedia.org/wiki/Unsharp_masking

    https://en.wikipedia.org/wiki/Erosion_(morphology)

    https://en.wikipedia.org/wiki/Dilation_(morphology)

    https://en.wikipedia.org/wiki/Opening_(morphology)

    https://en.wikipedia.org/wiki/Closing_(morphology)

    https://en.wikipedia.org/wiki/Top-hat_transform

    https://en.wikipedia.org/wiki/Mathematical_morphology

    https://en.wikipedia.org/wiki/Morphological_Gradient

    相关代码

    拉普拉斯滤波和加权均值滤波(主要是高斯滤波)实现图像锐化的代码比较常见,于是只给出如下代码。

    代码一,形态学梯度实现图像锐化

    #include <cv.h>
    #include <highgui.h>
    
    // 除了kcvMorphologicalSharpenLike
    // factor为正值时,会有锐化效果,为负值时,会有模糊效果。
    void kcvMorphologicalSharpenInt(const IplImage* src, IplImage* dst,
        double factor, IplConvKernel* element)
    {
        cvErode(src, dst, element, 1);
        cvSub(src, dst, dst);
        cvAddWeighted(src, 1, dst, factor, 0, dst);
    }
    
    void kcvMorphologicalSharpenExt(const IplImage* src, IplImage* dst,
        double factor, IplConvKernel* element)
    {
        cvDilate(src, dst, element, 1);
        cvSub(dst, src, dst);
        cvAddWeighted(src, 1, dst, -factor, 0, dst);
    }
    
    void kcvMorphologicalSharpen(const IplImage* src, IplImage* dst,
        double factor1, double factor2, IplConvKernel* element)
    {
        IplImage* tmp = cvCreateImage(cvGetSize(src), 8, src->nChannels);
        kcvMorphologicalSharpenInt(src, tmp, factor1, element);
        cvErode(src, dst, element, 1);
        cvSub(src, dst, dst);
        cvAddWeighted(tmp, 1, dst, factor2, 0, dst);
        cvReleaseImage(&tmp);
    }
    
    void kcvMorphologicalSharpenLike(const IplImage* src, IplImage* dst,
        double factor, IplConvKernel* element)
    {
        IplImage* tmp = cvCreateImage(cvGetSize(src), 8, src->nChannels);
        cvDilate(src, tmp, element, 1);
        cvErode(src, dst, element, 1);
        cvSub(tmp, dst, dst);
        cvAddWeighted(src, 1, dst, factor, 0, dst);
        cvReleaseImage(&tmp);
    }
    
    int main()
    {
        IplImage* src = cvLoadImage("lena.jpg", 1);
        IplImage* dst = cvCloneImage(src);
        IplConvKernel* element = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT, 0);
        int64 t1, t2;
    
        cvShowImage("src", src);
        t1 = cvGetTickCount();
        kcvMorphologicalSharpenInt(src, dst, 1, element);
        t2 = cvGetTickCount();
        printf("kcvMorphologicalSharpenInt %f ms
    ", (t2 - t1) / (1000 * cvGetTickFrequency()));
        cvShowImage("kcvMorphologicalSharpenInt", dst);
    
        t1 = cvGetTickCount();
        kcvMorphologicalSharpenExt(src, dst, 1, element);
        t2 = cvGetTickCount();
        printf("kcvMorphologicalSharpenExt %f ms
    ", (t2 - t1) / (1000 * cvGetTickFrequency()));
        cvShowImage("kcvMorphologicalSharpenExt", dst);
    
        t1 = cvGetTickCount();
        kcvMorphologicalSharpen(src, dst, 1, 1, element);
        t2 = cvGetTickCount();
        printf("kcvMorphologicalSharpen %f ms
    ", (t2 - t1) / (1000 * cvGetTickFrequency()));
        cvShowImage("kcvMorphologicalSharpen", dst);
    
        t1 = cvGetTickCount();
        kcvMorphologicalSharpenLike(src, dst, 1, element);
        t2 = cvGetTickCount();
        printf("kcvMorphologicalSharpenLike %f ms
    ", (t2 - t1) / (1000 * cvGetTickFrequency()));
        cvShowImage("kcvMorphologicalSharpenLike", dst);
    
        t1 = cvGetTickCount();
        kcvMorphologicalSharpenLike(src, dst, -1, element);
        t2 = cvGetTickCount();
        printf("kcvMorphologicalSharpenLike 2 %f ms
    ", (t2 - t1) / (1000 * cvGetTickFrequency()));
        cvShowImage("kcvMorphologicalSharpenLike 2", dst);
    
        cvWaitKey(0);
        cvDestroyAllWindows();
        cvReleaseImage(&src);
        cvReleaseImage(&dst);
        return 0;
    }
    

      

    代码二,顶帽底帽变换实现图像锐化

    close all
    I = imread('lena.jpg');
    imshow(I)
    se = strel('disk', 3);
    topHat = imtophat(I, se);
    botHat = imbothat(I, se);
    J = imadd(I, 1.5 * topHat);
    figure, imshow(J);
    J = imsubtract(I, 1.5 * botHat);
    figure, imshow(J);
    J = imsubtract(imadd(I, topHat), botHat);
    figure, imshow(J)
    J = imadd(imadd(I, topHat), botHat);
    figure, imshow(J)
    J = imsubtract(imsubtract(I, topHat), botHat);
    figure, imshow(J)

    正文

     

  • 相关阅读:
    gThumb 3.1.2 发布,支持 WebP 图像
    航空例行天气预报解析 metaf2xml
    Baruwa 1.1.2 发布,邮件监控系统
    Bisect 1.3 发布,Caml 代码覆盖测试
    MoonScript 0.2.2 发布,基于 Lua 的脚本语言
    Varnish 入门
    快速增量备份程序 DeltaCopy
    恢复模糊的图像 SmartDeblur
    Cairo 1.12.8 发布,向量图形会图库
    iText 5.3.4 发布,Java 的 PDF 开发包
  • 原文地址:https://www.cnblogs.com/quarryman/p/sharpening.html
Copyright © 2011-2022 走看看