图像处理之仿画笔效果一

简介: 图像处理之仿画笔效果一

图像处理之仿画笔效果一


仿画笔效果最终完成自动完成从一张RGB图像到手工油画效果根据设定好的几个基本参数,


本文章解释算法的前半部分。完整的算法介绍参见这里:


http://lvelho.impa.br/ip/papers/npar2000.pdf


StrokeAreas


本文的算法主要是通过输入像素计算Color Difference与moment值得到输出像素从而得到


图像上的画笔绘画区域(StrokeArea),需要输入的参数S决定中心像素p(x,y)的相邻区域的大


小。整个处理流程本质是对输入图像的一个非线性高通滤波,结果是图像中频率越强的区域


输出越黑,频率越低的输出越白。


颜色差值(Color Difference):


表示两个像素点RGB颜色值之间的差值,计算差值采用欧几里德距离公式。


图像力矩(Image Moments),计算公式如下: 1344775652_3054.gif


其中I为单色图像,否则RGB图像要分别代入RGB颜色分量


整个算法流程如下:


1.      根据输入图像生成一幅白色背景单色图像


2.      根据输入参数S计算出卷积区域大小


3.      对每个输入像素点完成卷积计算(注意是计算Color Difference)


4.      对输入像素点P0完成moment00计算


5.      归一化以后将输出像素输出到1中生成的图像对应(x,y)


程序效果:

1344775723_1683.png



另外一幅图效果参数s为30时候:

1344775797_4815.png


StrokeArea算法代码:

@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];
    getRGB( src, 0, 0, width, height, inPixels );
    int index = 0, index2 = 0;
    int semiRow = (int)(size/2); 
  int semiCol = (int)(size/2);
  int newX, newY;
  
  // initialize the color RGB array with zero...
  int[] rgb = new int[3];
  int[] rgb2 = new int[3];
  for(int i=0; i<rgb.length; i++) {
    rgb[i] = rgb2[i] = 0;
  }
  
  // start the algorithm process here!!
    for(int row=0; row<height; row++) {
      int ta = 0;
      for(int col=0; col<width; col++) {
        index = row * width + col;
        ta = (inPixels[index] >> 24) & 0xff;
        rgb[0] = (inPixels[index] >> 16) & 0xff;
        rgb[1] = (inPixels[index] >> 8) & 0xff;
        rgb[2] = inPixels[index] & 0xff;
            
            /* adjust region to fit in source image */
        // color difference and moment Image
            double moment = 0.0d;
            for(int subRow = -semiRow; subRow <= semiRow; subRow++) {
              for(int subCol = -semiCol; subCol <= semiCol; subCol++) {
                newY = row + subRow;
                newX = col + subCol;
                if(newY < 0) {
                  newY = 0;
                }
                if(newX < 0) {
                  newX = 0;
                }
                if(newY >= height) {
                  newY = height-1;
                }
                if(newX >= width) {
                  newX = width - 1;
                }
                index2 = newY * width + newX;
                rgb2[0] = (inPixels[index2] >> 16) & 0xff; // red
                rgb2[1] = (inPixels[index2] >> 8) & 0xff; // green
                rgb2[2] = inPixels[index2] & 0xff; // blue
                moment += colorDiff(rgb, rgb2);
              }
            }
            // calculate the output pixel value.
            int outPixelValue = clamp((int) (255.0d * moment / (size*size)));
            outPixels[index] = (ta << 24) | (outPixelValue << 16) | (outPixelValue << 8) | outPixelValue;
      }
    }
 
    setRGB( dest, 0, 0, width, height, outPixels );
    return dest;
}

转载文章请务必注明出自本博客

相关文章
|
22天前
|
算法 计算机视觉
图像处理之仿油画效果
图像处理之仿油画效果
9 0
|
1月前
如何用Qt抠一个圆形头像出来
如何用Qt抠一个圆形头像出来
|
8月前
|
C++
OpenCV-怀旧色滤镜
OpenCV-怀旧色滤镜
|
8月前
|
C++
OpenCV-PS扩散效果(毛玻璃)
OpenCV-PS扩散效果(毛玻璃)
|
8月前
|
异构计算
[笔记]音视频学习之SDL篇《十》绘制矩形,线条
[笔记]音视频学习之SDL篇《十》绘制矩形,线条
|
并行计算 iOS开发 MacOS
Metal每日分享,连环画滤镜和油画滤镜效果
Metal每日分享,连环画滤镜和油画滤镜效果
Metal每日分享,连环画滤镜和油画滤镜效果
|
算法
实现怀旧滤镜与连环画滤镜---OpenCV-Python开发指南(48)
实现怀旧滤镜与连环画滤镜---OpenCV-Python开发指南(48)
173 0
实现怀旧滤镜与连环画滤镜---OpenCV-Python开发指南(48)
|
计算机视觉
opencv 实现图像倒影(渐变)效果【源码】
opencv 实现图像倒影(渐变)效果【源码】
167 0
opencv 实现图像倒影(渐变)效果【源码】
|
数据库 数据库管理
我的Qt作品(5)使用Qt+Halcon实现模板匹配;支持ROI框选/橡皮擦功能
我的Qt作品(5)使用Qt+Halcon实现模板匹配;支持ROI框选/橡皮擦功能
942 0
我的Qt作品(5)使用Qt+Halcon实现模板匹配;支持ROI框选/橡皮擦功能
|
传感器
Emgu-WPF 激光雷达研究-绘制雷达图
原文:Emgu-WPF 激光雷达研究-绘制雷达图 硬件:Hokuyo URG04LX 环境:VS2017- win10- 64  Emgu_3.
987 0