将一副图像转换成油画

原创性声明:下面代码是本人改写自C#语言编写的软件改写自PhotoSprite (Version 3.0 。2006。由 联骏 编写)。由使用OpenCV300编写。

先看一下效果

算法未作不论什么优化,优化算法能够看Photoshop 油画效果滤镜

算法原理也不用细说了,源代码之前,了无秘密。

代码

cv::Mat OilPaint(cv::Mat I,int brushSize, int coarseness)
{
    assert(!I.empty());
    if (brushSize < 1) brushSize = 1;
    if (brushSize > 8) brushSize = 8;

    if (coarseness < 1) coarseness = 1;
    if (coarseness > 255) coarseness = 255;

    int width  = I.cols;
    int height = I.rows;

    int lenArray = coarseness + 1;
    int* CountIntensity = new int[lenArray];
    uint* RedAverage    = new uint[lenArray];
    uint* GreenAverage  = new uint[lenArray];
    uint* BlueAverage   = new uint[lenArray];

    /// 图像灰度化
    Mat gray;
    cvtColor(I,gray,COLOR_BGR2GRAY);

    /// 目标图像
    Mat dst = Mat::zeros(I.size(),I.type());

    for(int nY = 0;nY <height; nY++)
    {
        // 油画渲染范围上下边界
        int top = nY - brushSize;
        int bottom = nY+ brushSize+1;

        if(top<0) top = 0;
        if(bottom >=height) bottom = height - 1;

        for(int nX = 0;nX<width;nX++)
        {
            // 油画渲染范围左右边界
            int left = nX - brushSize;
            int right = nX +brushSize+1;

            if(left<0) left = 0;
            if(right>=width) right = width - 1;

            //初始化数组
            for(int i = 0;i <lenArray;i++)
            {
                CountIntensity[i] = 0;
                RedAverage[i] = 0;
                GreenAverage[i] = 0;
                BlueAverage[i] = 0;
            }

            // 下面这个内循环相似于外面的大循环
            // 也是油画特效处理的关键部分
            for(int j = top;j<bottom;j++)
            {
                for(int i = left;i<right;i++)
                {
                    uchar intensity = static_cast<uchar>(coarseness*gray.at<uchar>(j,i)/255.0);
                    CountIntensity[intensity]++;

                    RedAverage[intensity]  += I.at<Vec3b>(j,i)[2];
                    GreenAverage[intensity]+= I.at<Vec3b>(j,i)[1];
                    BlueAverage[intensity] += I.at<Vec3b>(j,i)[0];
                }
            }

            // 求最大值,并记录下数组索引
            uchar chosenIntensity = 0;
            int maxInstance = CountIntensity[0];
            for(int i=1;i<lenArray;i++)
            {
                if(CountIntensity[i]>maxInstance)
                {
                    chosenIntensity = (uchar)i;
                    maxInstance = CountIntensity[i];
                }
            }

            dst.at<Vec3b>(nY,nX)[2] = static_cast<uchar>(RedAverage[chosenIntensity] / static_cast<float>(maxInstance));
            dst.at<Vec3b>(nY,nX)[1] = static_cast<uchar>(GreenAverage[chosenIntensity] /  static_cast<float>(maxInstance));
            dst.at<Vec3b>(nY,nX)[0] = static_cast<uchar>(BlueAverage[chosenIntensity] /  static_cast<float>(maxInstance));
        }

    }

    delete [] CountIntensity;
    delete [] RedAverage;
    delete [] GreenAverage;
    delete [] BlueAverage;

#ifdef _DEBUG
    imshow("dst",dst);
    waitKey();
#endif

    return dst;
}

兴许

可是这种油画效果。还是感觉欠缺了什么。好吧,再拿了一张油画纹理渲染一下吧。事实上比較简单你能够使用正片叠底混合算法就能够了。

先看一下效果。(事实上你也能够觉得这种效果不好看,囧)

再来一张

还有一张

界面

界面致谢。人在旅途

好了,油画滤镜介绍完成。

转载请保留下面信息

作者 日期 联系方式
风吹夏天 2015年10月31日 wincoder#qq.com
时间: 2024-10-22 16:49:01

将一副图像转换成油画的相关文章

kinect2.0 基础篇第3篇 用C#在Visual Studio上编写把深度图像转换成彩色图像

本示例实现的功能有:有两个Radiobutton控件  选一个,点击启动按钮, 第一个是将深度图像转换成彩色图像 第二个是将深度图像做一些简单处理(例如太暗的调白一点) 涉及到一点遥感图像处理知识,将深度数据值转换为色调和饱和度 遥感图像处理那块不懂,有兴趣的自己可以研究研究,代码的基于kinect1的教程,慢慢尝试出来的,虽然功能实现了,但是原理还不是很懂 <Window x:Class="EnhancedDepthWPF.MainWindow" xmlns="htt

OCR文字识别软件中怎么把图像转换成HTML

之前给大家介绍了使用OCR文字识别软件ABBYY FineReader Mac版将PDF转换成HTML文档(详见PDF转换成HTML文档首选ABBYY Mac),其实ABBYY FineReader无论Mac版还是Windows版都可以实现这一点,除此之外还可以将图像文件转换成HTML文档,本文具体讲讲这一功能. ABBYY FineReader是一款OCR图文识别软件,当前最新版本为ABBYY FineReader 12,可快速方便地将扫描纸质文档.PDF文件和数码相机的图像转换成可编辑.可搜

Android将图像转换成流存储与将流转换成图像

1.将图片转换成二进制流 public byte[] getBitmapByte(Bitmap bitmap){ ByteArrayOutputStream out = new ByteArrayOutputStream(); //参数1转换类型,参数2压缩质量,参数3字节流资源 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); try { out.flush(); out.close(); } catch (IOException e

如何把drawing图像转换成wpf控件的source

此例以canvas为例 <Canvas>  <Image Stretch="Fill" Width="100" Height="100" x:Name="myImage"/></Canvas> 一种方法:System.Drawing.Image bmp=...; // 自己初始化的有效的 imageSystem.IO.MemoryStream ms = new System.IO.Memor

如何用ABBYY把PDF转换成PPT

在电子科技迅速发展的今天,文件格式转换并不是什么稀罕事,因为现在都是电子化办公,出现很多文件格式,但是不同的场合需要的格式不同,所以常常需要进行文件格式的转换.PDF转换成PPT也是众多文件格式转换中的一种,这里小编给大家介绍一种PDF转换成PPT的好方法. 首先需要下载安装ABBYY FineReader 12OCR文字识别软件,这是转换的关键,没错,今天要给大家介绍的正式这款转换器.ABBYY FineReader是一款功能强大.界面简洁.操作简单的PDF转PPT软件,还可快速.方便地将扫描

ABBYY将JPEG文件转换成Word文档的方法

日常工作中处理JPEG格式的图像文件时,有时需要转换成Word文档进行编辑,市场上应用而生了很多转换工具,相信不少人听说过OCR(光学字符识别)软件,可以用来转换图像文件,而在OCR软件中, ABBYY FineReader 12已被越来越多的企业和个人熟知,在日常工作中的应用范围也越来月广泛,本文主要教大家使用ABBYY FineReader 12将JPEG文件转换成Word文档. ABBYY FineReader 12是一款OCR图文识别软件,可快速方便地将扫描纸质文档.PDF文件和数码相机

ABBYY把pdf转换成word的方法

有时候我们在网上下载的资料文献是PDF格式文档,遇到喜欢的字句总忍不住想要收藏起来,但是PDF文档不同于普通的Word文档可以直接进行复制粘贴,需要下载安装相关的编辑工具,才能对文字内容进行编辑.倒不如直接将PDF转换成我们熟悉的Word文档,编辑文字操作起来也更加方便些.那么PDF转换成Word文档操作起来难吗?懒人自有妙招,小编手把手教你如何把PDF转换成Word文档. 这种文件格式转换方法非常简单,用户只需下载安装ABBYY FineReader 12 OCR文字识别软件即可,操作步骤十分

怎么把图像文件转换成Excel

图像文件可以通过ABBYY FineReader 12 OCR文字识别软件转换为Word文档,同样也能用来转换图像为Excel电子表格,过程与前者大同小异,只要掌握了ABBYY FineReader的使用技巧,你想要的格式都能帮你实现,今天我们就来讲讲如何使用ABBYY FineReader将图像文件转换为Excel电子表格. ABBYY FineReader 12是一款OCR图文识别软件,能够快速方便地将扫描纸质文档.PDF文件和数码相机的图像转换成可编辑.可搜索的文本,包括Word.Exce

&lt;p&gt;&lt;span style=&quot;font-size:14px&quot;&gt;近期须要批量将PNM&amp;#26684;式的文件转换成GIF文件。我尝试了例如以下的图像转换工具:&lt;/span&gt;&lt;/p&gt;

近期须要批量将PNM格式的文件转换成GIF文件.我尝试了例如以下的图像转换工具: ImageBatch:全然免费,但只支持PNG JPEG BMP GIF四种格式 OfficeConverter:在线转换软件,支持全部图像格式的相互转换.大量处理图像时须要支付一定费用,否则效率低 Pixillion:支持全部格式,试用版只最多支持5个文件为一组batch的处理,使用100次以后必须付费使用 因为上述工具均不能满足我的须要(不想使用付费软件),我尝试搜索PNM转GIF文件的软件包,发现能够安装Py