zoukankan      html  css  js  c++  java
  • 将一副图像转换成油画

    原创性声明:下面代码是本人改写自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
  • 相关阅读:
    iOS 9正式版开始推送 升级机型非常广泛
    dataWithContentsOfURL报错问题
    Android double输出时保留两位小数
    cornerstone忽略显示.DS_Store文件
    Couldn't open file on client side, trying server side 错误解决
    @SuppressWarnings有什么用处?
    iOS下UITableView的单元格重用逻辑
    根据滑动显隐状态栏的iOS实现
    Runloop之个人理解
    聚合支付概念
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7289369.html
Copyright © 2011-2022 走看看