图像分析之图像锐化

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

更新记录

本文持续更新!如文中有错误,或你对本文有疑问或建议,欢迎留言或发邮件至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\n", (t2 - t1) / (1000 * cvGetTickFrequency()));
    cvShowImage("kcvMorphologicalSharpenInt", dst);

    t1 = cvGetTickCount();
    kcvMorphologicalSharpenExt(src, dst, 1, element);
    t2 = cvGetTickCount();
    printf("kcvMorphologicalSharpenExt %f ms\n", (t2 - t1) / (1000 * cvGetTickFrequency()));
    cvShowImage("kcvMorphologicalSharpenExt", dst);

    t1 = cvGetTickCount();
    kcvMorphologicalSharpen(src, dst, 1, 1, element);
    t2 = cvGetTickCount();
    printf("kcvMorphologicalSharpen %f ms\n", (t2 - t1) / (1000 * cvGetTickFrequency()));
    cvShowImage("kcvMorphologicalSharpen", dst);

    t1 = cvGetTickCount();
    kcvMorphologicalSharpenLike(src, dst, 1, element);
    t2 = cvGetTickCount();
    printf("kcvMorphologicalSharpenLike %f ms\n", (t2 - t1) / (1000 * cvGetTickFrequency()));
    cvShowImage("kcvMorphologicalSharpenLike", dst);

    t1 = cvGetTickCount();
    kcvMorphologicalSharpenLike(src, dst, -1, element);
    t2 = cvGetTickCount();
    printf("kcvMorphologicalSharpenLike 2 %f ms\n", (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)

正文

 

posted @ 2016-01-08 15:25  quarryman  阅读(3299)  评论(0编辑  收藏  举报