GDAL 图像锐化

  • 简介
  • 拉普拉斯(Laplace)算子
    • 部分代码:
  • 索贝尔(Sobel)算子
    • 部分代码:
  • 处理效果
    • 原图
    • (Laplace)
    • (Sobel)
  • 结尾
  • 参考文章

简介

图像锐化(image sharpening)是补偿图像的轮廓,增强图像的边缘及灰度跳变的部分,使图像变得清晰,分为空间域处理和频域处理两类。图像锐化是为了突出图像上地物的边缘、轮廓,或某些线性目标要素的特征。这种滤波方法提高了地物边缘与周围像元之间的反差,因此也被称为边缘增强。

各种算子是图像锐化的核心,GDAL中没有提供相应的方法,所以我参考了网上C++的图像处理算法和GDAL进行了融合:

拉普拉斯(Laplace)算子

拉普拉斯算子是一个是n维欧几里德空间中的一个二阶微分算子,它的定义如下:

在x方向上

在y方向上

合起来就是

拉普拉斯强调的是图像中灰度的突变,并不强调图像的灰度缓变(灰度缓变由一阶微分,也就是梯度,图像应用是sobel算子,具体下面介绍)

根据上边的表达式,可以确定拉普拉斯算子的模板:

部分代码:

可根据我的另一篇博客(图像平滑),通过改动算法核心写出锐化函数。

    int laplace4[3][3] = { 0, -1, 0, -1, 5, -1, 0, -1, 0 };//laplace锐化模板,4邻域int laplace8[3][3] = { -1, -1, -1, -1, 9, -1, -1, -1, -1 };//laplace锐化模板,8邻域int m,n;//平滑算子也是通过模板进行处理的,所以可以把平滑处理和锐化处理通过一个函数实现int biBitCount = 8;//红色波段处理//分配新像素组的空间int lineByte = (nImgSizeX * biBitCount / 8 + 3) / 4 * 4;rbandsmooth = new unsigned char[lineByte * nImgSizeY];//进行模板操作for (int i = 0; i < nImgSizeY; i++){for (int j = 0; j < nImgSizeX; j++){if (i == 0 || j == 0 || i == nImgSizeY - 1 || j == nImgSizeX - 1)rbandsmooth[i*nImgSizeX + j] = rband[i*nImgSizeX + j];else{int sum = 0;for (m = i - 1; m < i + 2; m++)for (n = j - 1; n < j + 2; n++){sum += (*(rband + m*nImgSizeX  + n  ))*laplace8[n - j + 1][m - i + 1] / 1;}//8位BMP中一个像素值,对应调色板中索引号为该像素值的项所存放的RGB色彩//所以像素值范围为0~255,像素值小于0就取0,大于255就取255sum = (sum > 0) ? sum : 0;sum = (sum > 255) ? 255 : sum;rbandsmooth[i*nImgSizeX + j] = sum;}}}//绿色波段处理//分配新像素素组的空间gbandsmooth = new unsigned char[lineByte * nImgSizeY];//进行模板操作for (int i = 0; i < nImgSizeY; i++){for (int j = 0; j < nImgSizeX; j++){if (i == 0 || j == 0 || i == nImgSizeY - 1 || j == nImgSizeX - 1)gbandsmooth[i*nImgSizeX  + j] = gband[i*nImgSizeX  + j];else{int sum = 0;for (m = i - 1; m < i + 2; m++)for (n = j - 1; n < j + 2; n++){sum += (*(gband + m*nImgSizeX  + n  ))*laplace8[n - j + 1][m - i + 1] / 1;}//8位BMP中一个像素值,对应调色板中索引号为该像素值的项所存放的RGB色彩//所以像素值范围为0~255,像素值小于0就取0,大于255就取255sum = (sum > 0) ? sum : 0;sum = (sum > 255) ? 255 : sum;gbandsmooth[i*nImgSizeX + j]  = sum;}}}//蓝色波段处理//分配新像素素组的空间bbandsmooth = new unsigned char[lineByte * nImgSizeY];//进行模板操作for (int i = 0; i < nImgSizeY; i++){for (int j = 0; j < nImgSizeX; j++){if (i == 0 || j == 0 || i == nImgSizeY - 1 || j == nImgSizeX - 1)bbandsmooth[i*nImgSizeX + j] = bband[i*nImgSizeX + j];else{int sum = 0;for (m = i - 1; m < i + 2; m++)for (n = j - 1; n < j + 2; n++){sum += (*(bband + m*nImgSizeX  + n  ))*laplace8[n - j + 1][m - i + 1] / 1;}//8位BMP中一个像素值,对应调色板中索引号为该像素值的项所存放的RGB色彩//所以像素值范围为0~255,像素值小于0就取0,大于255就取255sum = (sum > 0) ? sum : 0;sum = (sum > 255) ? 255 : sum;bbandsmooth[i*nImgSizeX + j] = sum;}}}

索贝尔(Sobel)算子

Sobel算子是像素图像边缘检测中最重要的算子之一,在机器学习、数字媒体、计算机视觉等信息科技领域起着举足轻重的作用。在技术上,它是一个离散的一阶差分算子,用来计算图像亮度函数的一阶梯度之近似值。在图像的任何一点使用此算子,将会产生该点对应的梯度矢量或是其法矢量。
索贝尔(Sobel)算子定义:

该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像,其公式如下:

图像的每一个像素的横向及纵向梯度近似值可用以下的公式结合,来计算梯度的大小。

可用以下公式计算梯度方向。

在以上例子中,如果以上的角度Θ等于零,即代表图像该处拥有纵向边缘,左方较右方暗。

部分代码:

与拉普拉斯(Laplace)算子相比较,思路大同小异,主要是Sobel算法有两个算子,需要分别进行计算。

    int sobelx[3][3] = { 1,2,1,0,0,0,-1,-2,-1};//sobelxint sobely[3][3] = { 1,0,-1,2,0,-2,1,0,-1};//sobelyint m,n;//平滑算子也是通过模板进行处理的,所以可以把平滑处理和锐化处理通过一个函数实现unsigned char *imagedatasobelx;unsigned char *imagedatasobely;//分配新像素组的空间int lineByte = (nImgSizeX * biBitCount / 8 + 3) / 4 * 4;rbandsmooth = new unsigned char[lineByte * nImgSizeY];imagedatasobelx = new unsigned char[lineByte * nImgSizeY];imagedatasobely = new unsigned char[lineByte * nImgSizeY];//进行模板操作for (int i = 0; i < nImgSizeY; i++){for (int j = 0; j < nImgSizeX; j++){if (i == 0 || j == 0 || i == nImgSizeY - 1 || j == nImgSizeX - 1){*(imagedatasobelx + i*nImgSizeX + j) = rband[i*nImgSizeX + j];*(imagedatasobely + i*nImgSizeX + j) = rband[i*nImgSizeX + j];}else{int sumx = 0;int sumy = 0;for (int m = i - 1; m < i + 2; m++)for (int n = j - 1; n < j + 2; n++){sumx += (*(rband + m*nImgSizeX + n))*sobelx[n - j + 1][m - i + 1] / 1;sumy += (*(rband + m*nImgSizeX + n))*sobely[n - j + 1][m - i + 1] / 1;}//8位BMP中一个像素值,对应调色板中索引号为该像素值的项所存放的RGB色彩//所以像素值范围为0~255,像素值小于0就取0,大于255就取255sumx = (sumx > 0) ? sumx : 0;sumx = (sumx >255) ? 255 : sumx;imagedatasobelx[i*nImgSizeX + j] = sumx;//sobelxsumy = (sumy > 0) ? sumy : 0;sumy = (sumy >255) ? 255 : sumy;imagedatasobely[i*nImgSizeX + j] = sumy;//sobelyrbandsmooth[i*nImgSizeX + j] =imagedatasobelx[i*nImgSizeX + j] + imagedatasobely[i*nImgSizeX + j];}}}//gbandgbandsmooth = new unsigned char[lineByte * nImgSizeY];imagedatasobelx = new unsigned char[lineByte * nImgSizeY];imagedatasobely = new unsigned char[lineByte * nImgSizeY];//进行模板操作for (int i = 0; i < nImgSizeY; i++){for (int j = 0; j < nImgSizeX; j++){if (i == 0 || j == 0 || i == nImgSizeY - 1 || j == nImgSizeX - 1){*(imagedatasobelx + i*nImgSizeX + j) = gband[i*nImgSizeX + j];*(imagedatasobely + i*nImgSizeX + j) = gband[i*nImgSizeX + j];}else{int sumx = 0;int sumy = 0;for (int m = i - 1; m < i + 2; m++)for (int n = j - 1; n < j + 2; n++){sumx += (*(gband + m*nImgSizeX + n))*sobelx[n - j + 1][m - i + 1] / 1;sumy += (*(gband + m*nImgSizeX + n))*sobely[n - j + 1][m - i + 1] / 1;}//8位BMP中一个像素值,对应调色板中索引号为该像素值的项所存放的RGB色彩//所以像素值范围为0~255,像素值小于0就取0,大于255就取255sumx = (sumx > 0) ? sumx : 0;sumx = (sumx >255) ? 255 : sumx;imagedatasobelx[i*nImgSizeX + j] = sumx;//sobelxsumy = (sumy > 0) ? sumy : 0;sumy = (sumy >255) ? 255 : sumy;imagedatasobely[i*nImgSizeX + j] = sumy;//sobelygbandsmooth[i*nImgSizeX + j] =imagedatasobelx[i*nImgSizeX + j] + imagedatasobely[i*nImgSizeX + j];}}}//bbandbbandsmooth = new unsigned char[lineByte * nImgSizeY];imagedatasobelx = new unsigned char[lineByte * nImgSizeY];imagedatasobely = new unsigned char[lineByte * nImgSizeY];//进行模板操作for (int i = 0; i < nImgSizeY; i++){for (int j = 0; j < nImgSizeX; j++){if (i == 0 || j == 0 || i == nImgSizeY - 1 || j == nImgSizeX - 1){*(imagedatasobelx + i*nImgSizeX + j) = bband[i*nImgSizeX + j];*(imagedatasobely + i*nImgSizeX + j) = bband[i*nImgSizeX + j];}else{int sumx = 0;int sumy = 0;for (int m = i - 1; m < i + 2; m++)for (int n = j - 1; n < j + 2; n++){sumx += (*(bband + m*nImgSizeX + n))*sobelx[n - j + 1][m - i + 1] / 1;sumy += (*(bband + m*nImgSizeX + n))*sobely[n - j + 1][m - i + 1] / 1;}//8位BMP中一个像素值,对应调色板中索引号为该像素值的项所存放的RGB色彩//所以像素值范围为0~255,像素值小于0就取0,大于255就取255sumx = (sumx > 0) ? sumx : 0;sumx = (sumx >255) ? 255 : sumx;imagedatasobelx[i*nImgSizeX + j] = sumx;//sobelxsumy = (sumy > 0) ? sumy : 0;sumy = (sumy >255) ? 255 : sumy;imagedatasobely[i*nImgSizeX + j] = sumy;//sobelybbandsmooth[i*nImgSizeX + j] =imagedatasobelx[i*nImgSizeX + j] + imagedatasobely[i*nImgSizeX + j];}}}

处理效果

原图

(Laplace)

这里有个问题,在拉普拉斯算子中间是,4和8,但是用原版算子的处理结果是这样的:

看起来是做了边缘提取;
后来经过修改,将4邻域和8邻域改成了5和9,就出了这个结果:

看起来比原来清楚许多,实际应用效果会更明显。

(Sobel)

索贝尔算子还是有问题,可能是因为从灰度图像的锐化移植为真彩色图像时的问题,还需要进行修改,结果也像是做了边缘提取:

结尾

因为之前没有太涉及到算法问题,而且GDAL的锐化方面还没有太多的过来人,所以经验不多,还需要人们探索,如有不足请多指教。

参考文章

https://www.cnblogs.com/fydeblog/p/6748411.html
https://blog.csdn.net/wanty_chen/article/details/80336986
https://blog.csdn.net/White_Idiot/article/details/51794364

GDAL 遥感 图像处理 锐化(Laplace算子、Sobel算子)相关推荐

  1. 图像处理中的梯度、导数如何求?(Robert算子,Sobel算子,Prewitt算子,Laplace算子)

    梯度的求法是多种多样的,根据不同的处理需要选择合适的算子(模版). 1.水平垂直差分法 2.Robert 梯度算子 3.Sobel算子               垂直方向               ...

  2. 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...

  3. 一文解决Opencv四大经典算子——sobel算子、scharr算子、laplacian算子、canny算子

    Opencv四大算子 Sobel算子 Scharr算子 laplacian算子 canny算子 总结 边缘是像素值发生跃迁的位置,是图像的显著特征之一,在图像特征提取,对象检测,模式识别等方面都有重要 ...

  4. OpenCV图像处理使用笔记(八)——Sobel算子

    前言 前面博客讲了矩阵之间的卷积操作,在图像处理中,使用一些标准的模板的卷积核与原图像进行运算,可以改变像素强度,从而影响周围其他像素的强度,常用于图像模糊.锐化及边缘检测等. Sobel算子 1.S ...

  5. opencv-python图像处理 ----图像梯度、Sobel算子

    一.图像的梯度处理 1.Sobel算子 梯度可以按照x方向或者y方向求梯度,其实就是在看像素点的差异变化情况,比如黑白物体的交界,其像素值变化差异是非常大的. 求梯度计算使用的函数就叫做Sobel算子 ...

  6. Opencv3 Robert算子 Sobel算子 拉普拉斯算子 自定义卷积核——实现渐进模糊

    #include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace c ...

  7. python VTK(十三) ----图像边缘检测 梯度算子 sobel算子

    梯度算子 import vtk reader = vtk.vtkJPEGReader() # 读入灰度图 reader.SetFileName(r'E:\lena-gray.jpg') reader. ...

  8. 【OpenCV 例程200篇】64. 图像锐化——Sobel 算子

    [OpenCV 例程200篇]64. 图像锐化--Sobel 算子 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 3 ...

  9. Matlab仿照Sobel算子实现±45°图像细节检测和图像锐化

    1. 要求 参考Sobel算子能够检测x和y方向的原理,设计合适的模板,能够检测±45°斜方向上的图像细节,分别输出正45度方向和负45度方向的图像细节,以及两者相叠加后的图像结果.将取的图像细节,叠 ...

最新文章

  1. MySQL-锁表处理
  2. 老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现
  3. [CTO札记]互联网一定要免费吗?网络文学是继网络游戏后又一成功的收费模式...
  4. linux加密解密基础、PKI及SSL、创建私有CA
  5. java验证码识别--2
  6. SAP C4C 和 ERP 中的外部定价模块 - External Pricing原理介绍
  7. GLSurfaceView基础学习笔记
  8. C语言和设计模式(访问者模式)
  9. 记录学习——算法时间复杂度求法
  10. bootstrap 树
  11. [二分]TYVJ1359 收入计划
  12. 如何制定软件项目进度表
  13. Little Gyro and Sort(第二届中国计量大学ACM程序设计竞赛个人赛)
  14. 磁盘的组成、MBR、GPT
  15. 【观察】海外本地化机遇与挑战并存,跨境电商如何跑出“加速度”?
  16. Linux内核notifier机制通知链
  17. 华为到底玩的哪些汽车技术?
  18. 【技术认证题库】齐治初级运维安全认证——RIS堡垒机习题
  19. math.h数学函数
  20. ASPICE SWE3之——模型生成软件详细设计1 配置

热门文章

  1. CF1603C Extreme Extension
  2. n+nn+nnn+...+n...=n...
  3. 蜘蛛池泛目录seo必备站长源码
  4. 数据结构:数组和链表的区别以及各自的优缺点
  5. 笔记本/台式机作为扩展屏
  6. 17.Rust中函数式语言功能:迭代器与闭包
  7. 前端小白-HTML简介
  8. 浅谈c++中upper_bound与lower_bound的用法
  9. 【NumPy中数组创建】
  10. mapbox tippecanoe切矢量瓦片参数设置和注意事项