图像处理之应用卷积– 轧花与边缘检测

简介: 图像处理之应用卷积– 轧花与边缘检测

关于什么是卷积,如何理解卷积 参见这里:

http://blog.csdn.net/jia20003/article/details/7038938

一:轧花

轧花算子(embossfilter)

对一幅数字图像一阶微分结果即可得到轧花效果,根据不同的算子,轧花又


可以分为凹效果与凸效果两种。两个个最简单的轧花算子为:

0_1332040484RoK3.png


轧花算子又称为双极性算子,1对图像的贡献意味着平滑,-1对图像的贡献


意味着突出细节,于是最终就得出了双极性的轧花效果。



处理过程:


a.      读取图像像素


b.      使用轧花算子完成对像素数组的卷积操作


c.      整体亮度提升效果– 高斯亮度/基于阈值/直接常量提升



轧花滤镜效果:左边为原图, 右边为轧花处理以后效果

0_1332040416zaDW.jpg


二:边缘提取


Edge detection是图像处理中非常重要而且也是十分常用的图像处理手段之一,边缘提取是


图像二值化的基本步骤之一。边缘提取从本质上来说是高通滤波,从数字信号的角度看,就


是要保留高频信号,去掉低频信号,因此边缘提取有很多频率域算子,将图像完成FFT之后


在频率域完成高通滤波再转到空间域。显然计算量比较大,空间域最经典的边缘提取算法之


一Candy Edge Detection有着非常好的效果。



这里只是抛砖引玉,完成一个最简单基于卷积的空间域边缘提取算子,算子为:

0_1332040503Mek1.png


完成卷积以后的效果如下:

0_13320405257474.jpg



对于灰度图完成边缘提取以后效果如下:


0_1332040538025m.png

基于卷积还可以完成图像的锐化(Sharp Filter),让图像上的差异更加明显。


一个简单的Sharp Filter可以为

0_1332040566L6mX.png


得到的效果如下:


0_1332040584Q10q.png

完成轧花卷积的代码如下:

  @Override
  public BufferedImage filter(BufferedImage src, BufferedImage dest) {
    int width = src.getWidth();
        int height = src.getHeight();
 
        if ( dest == null )
            dest = createCompatibleDestImage( src, null );
 
        int[] inPixels = new int[width*height];
        int[] outPixels = new int[width*height];
        src.getRGB( 0, 0, width, height, inPixels, 0, width );
    int index = 0;
    int index2 = 0;
    int r=0, g=0, b=0;
    for ( int y = 0; y < height; y++ ) {
      for ( int x = 0; x < width; x++ ) {
        int ta = 255, tr = 0, tg = 0, tb = 0;
        for(int fr = 0; fr < filterRow; fr++) {
          int rowoffset = y + fr;
          if(rowoffset < 0 || rowoffset >=height) {
            rowoffset = y;
          }
          for(int fc = 0; fc < filterCol; fc++) {
            int coloffset = fc + x;
            if(coloffset < 0 || coloffset >= width) {
              coloffset = x;
            }
            index2 = rowoffset * width + coloffset;
            int rgb1 = inPixels[index2];
            int r1 = (rgb1 >> 16) & 0xff;
            int g1 = (rgb1 >> 8) & 0xff;
            int b1 = rgb1 & 0xff;
            if(isOUT) {
              tr += r1 * outfilter[fr][fc];
              tg += g1 * outfilter[fr][fc];
              tb += b1 * outfilter[fr][fc];
            } else {
              tr += r1 * infilter[fr][fc];
              tg += g1 * infilter[fr][fc];
              tb += b1 * infilter[fr][fc];
            }
          }
        }
        
        tr += COLORCONSTANTS;
        tg += COLORCONSTANTS;
        tb += COLORCONSTANTS;
        r = PixelUtils.clamp(tr);
        g = PixelUtils.clamp(tg);
        b = PixelUtils.clamp(tb);
        outPixels[index] = (ta << 24) | (r << 16) | (g << 8) | b;
        index++;
      }
    }
        dest.setRGB( 0, 0, width, height, outPixels, 0, width );
        return dest;
  }

完成简单边缘检测的代码如下:

  private void filter(int[] inPixels, int[] outPixels, int height, int width, double[][] filterKernel) {
    int index = 0;
    int index2 = 0;
    int r=0, g=0, b=0;
    int semiColumn = filterKernel.length/2;
    int semiRow = filterKernel[0].length/2;
    for ( int y = 0; y < height; y++ ) {
      for ( int x = 0; x < width; x++ ) {
        int ta = 255, tr = 0, tg = 0, tb = 0;
        for(int fr = -semiRow; fr <= semiRow; fr++) {
          int rowoffset = y + fr;
          if(rowoffset < 0 || rowoffset >=height) {
            rowoffset = y;
          }
          for(int fc = -semiColumn; fc <= semiColumn; fc++) {
            int coloffset = fc + x;
            if(coloffset < 0 || coloffset >= width) {
              coloffset = x;
            }
            index2 = rowoffset * width + coloffset;
            int rgb1 = inPixels[index2];
            int r1 = (rgb1 >> 16) & 0xff;
            int g1 = (rgb1 >> 8) & 0xff;
            int b1 = rgb1 & 0xff;
            tr += ((double)r1 * filterKernel[fr + semiRow][fc + semiColumn]);
            tg += ((double)g1 * filterKernel[fr + semiRow][fc + semiColumn]);
            tb += ((double)b1 * filterKernel[fr + semiRow][fc + semiColumn]);
          }
        }
        
        if(enhanceBrightness) {
          tr += COLORCONSTANTS;
          tg += COLORCONSTANTS;
          tb += COLORCONSTANTS;
        }
        r = PixelUtils.clamp(tr);
        g = PixelUtils.clamp(tg);
        b = PixelUtils.clamp(tb);
        outPixels[index] = (ta << 24) | (r << 16) | (g << 8) | b;
        index++;
      }
    }
  }

相关实践学习
【玩转ComfyUI】基于函数计算一键部署AI生图平台ComfyUI
本次实验将带大家通过使用阿里云产品函数计算FC,快速使用ComfyUI实现更高质量的图像生成。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
相关文章
|
API 开发工具 iOS开发
iOS 开发高效率工具包:10 大必备工具
iOS 开发高效率工具包:10 大必备工具
439 1
|
Web App开发 前端开发 IDE
Airtest-Selenium实操小课①:爬取新榜数据
Airtest-Selenium实操小课①:爬取新榜数据
308 0
|
机器学习/深度学习 人工智能 安全
基于YOLOv8的路面缺陷(路面裂缝、井盖、坑洼路面)识别项目【完整源码数据集+PyQt5界面+完整训练流程+开箱即用!】
本项目基于YOLOv8与PyQt5,打造路面缺陷检测系统,支持裂缝、井盖、坑洼识别,涵盖图片、视频、摄像头等多种输入方式。提供完整训练数据、预训练模型及图形化界面,开箱即用,本地运行,方便二次开发。适用于智慧城市建设与道路安全巡检,推动AI检测技术实际应用。项目包含源码、数据集、训练代码,支持科研学习与工程实战。
|
开发者 图形学 API
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
982 0
|
数据采集 机器学习/深度学习 数据挖掘
清洗数据的魔法:让你的数据干净又整洁
清洗数据的魔法:让你的数据干净又整洁
1026 2
|
前端开发 开发者 C++
独家揭秘:前端大牛们如何高效学习新技术,保持竞争力!
【10月更文挑战第31天】前端技术飞速发展,如何高效学习新技术成为关键。本文通过对比普通开发者与大牛们的策略,揭示了高效学习的秘诀:明确目标、主动探索、系统资源、实践应用和持续学习。通过这些方法,大牛们能更好地掌握新技术,保持竞争力。示例代码展示了如何通过实践加深理解。
319 4
|
安全 5G 网络性能优化
5G中的AMF和SMF:概述和功能
【8月更文挑战第31天】
2532 0
|
机器学习/深度学习 自然语言处理 并行计算
【YOLOv8改进 -注意力机制】Mamba之MLLAttention :基于Mamba和线性注意力Transformer的模型
YOLOv8专栏探讨了该目标检测模型的创新改进,包括使用Mamba模型的线性注意力Transformer变体,称为MLLA。Mamba的成功关键在于遗忘门和块设计,MLLA结合了这些优点,提升了视觉任务的性能。文章提供全面分析,并提出MLLA模型,其在效率和准确性上超过多种视觉模型。论文和代码可在提供的链接中找到。MLLA Block的代码示例展示了如何整合关键组件以实现高效运算。更多配置详情见相关链接。
|
机器学习/深度学习 算法
|
Windows
Windows批处理(BAT)文件执行时“一闪而过或闪退”问题及解决方法
Windows批处理(BAT)文件执行时“一闪而过或闪退”问题及解决方法
10377 1

热门文章

最新文章