GDAL 遥感 图像处理 锐化(Laplace算子、Sobel算子)
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算子)相关推荐
- 图像处理中的梯度、导数如何求?(Robert算子,Sobel算子,Prewitt算子,Laplace算子)
梯度的求法是多种多样的,根据不同的处理需要选择合适的算子(模版). 1.水平垂直差分法 2.Robert 梯度算子 3.Sobel算子 垂直方向 ...
- 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...
- 一文解决Opencv四大经典算子——sobel算子、scharr算子、laplacian算子、canny算子
Opencv四大算子 Sobel算子 Scharr算子 laplacian算子 canny算子 总结 边缘是像素值发生跃迁的位置,是图像的显著特征之一,在图像特征提取,对象检测,模式识别等方面都有重要 ...
- OpenCV图像处理使用笔记(八)——Sobel算子
前言 前面博客讲了矩阵之间的卷积操作,在图像处理中,使用一些标准的模板的卷积核与原图像进行运算,可以改变像素强度,从而影响周围其他像素的强度,常用于图像模糊.锐化及边缘检测等. Sobel算子 1.S ...
- opencv-python图像处理 ----图像梯度、Sobel算子
一.图像的梯度处理 1.Sobel算子 梯度可以按照x方向或者y方向求梯度,其实就是在看像素点的差异变化情况,比如黑白物体的交界,其像素值变化差异是非常大的. 求梯度计算使用的函数就叫做Sobel算子 ...
- Opencv3 Robert算子 Sobel算子 拉普拉斯算子 自定义卷积核——实现渐进模糊
#include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace c ...
- python VTK(十三) ----图像边缘检测 梯度算子 sobel算子
梯度算子 import vtk reader = vtk.vtkJPEGReader() # 读入灰度图 reader.SetFileName(r'E:\lena-gray.jpg') reader. ...
- 【OpenCV 例程200篇】64. 图像锐化——Sobel 算子
[OpenCV 例程200篇]64. 图像锐化--Sobel 算子 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 3 ...
- Matlab仿照Sobel算子实现±45°图像细节检测和图像锐化
1. 要求 参考Sobel算子能够检测x和y方向的原理,设计合适的模板,能够检测±45°斜方向上的图像细节,分别输出正45度方向和负45度方向的图像细节,以及两者相叠加后的图像结果.将取的图像细节,叠 ...
最新文章
- MySQL-锁表处理
- 老赵谈IL(3):IL可以看到的东西,其实大都也可以用C#来发现
- [CTO札记]互联网一定要免费吗?网络文学是继网络游戏后又一成功的收费模式...
- linux加密解密基础、PKI及SSL、创建私有CA
- java验证码识别--2
- SAP C4C 和 ERP 中的外部定价模块 - External Pricing原理介绍
- GLSurfaceView基础学习笔记
- C语言和设计模式(访问者模式)
- 记录学习——算法时间复杂度求法
- bootstrap 树
- [二分]TYVJ1359 收入计划
- 如何制定软件项目进度表
- Little Gyro and Sort(第二届中国计量大学ACM程序设计竞赛个人赛)
- 磁盘的组成、MBR、GPT
- 【观察】海外本地化机遇与挑战并存,跨境电商如何跑出“加速度”?
- Linux内核notifier机制通知链
- 华为到底玩的哪些汽车技术?
- 【技术认证题库】齐治初级运维安全认证——RIS堡垒机习题
- math.h数学函数
- ASPICE SWE3之——模型生成软件详细设计1 配置
热门文章
- CF1603C Extreme Extension
- n+nn+nnn+...+n...=n...
- 蜘蛛池泛目录seo必备站长源码
- 数据结构:数组和链表的区别以及各自的优缺点
- 笔记本/台式机作为扩展屏
- 17.Rust中函数式语言功能:迭代器与闭包
- 前端小白-HTML简介
- 浅谈c++中upper_bound与lower_bound的用法
- 【NumPy中数组创建】
- mapbox tippecanoe切矢量瓦片参数设置和注意事项