zoukankan      html  css  js  c++  java
  • 在layerModelBlending的PR过程中出现的问题和解决方法

    一、情况说明
    layerModelBlending是属于photo 模块下的算法,我很大程度上参考seamlessclone进行实现。这是我第一次编写功能模块,不同于之前的教程或者是某些参数的修改。这里的操作需要更多的工作。这里将过程中出现的问题和解决方法进行分析,作为经验。
    二、问题分析
    主要是修改两个地方,一个是photo.hpp,主要是添加头文件;
    //! layerModelBlending algorithm flags
    enum
    {
        DARKEN = 1,                //min(Target,Blend)
        MULTIPY = 2,               //Target * Blend      
        COLOR_BURN = 3,            //1 - (1-Target) / Blend         
        LINEAR_BRUN = 4,            //Target + Blend - 1         
        LIGHTEN = 5,               //max(Target,Blend)       
        SCREEN = 6,                //1 - (1-Target) * (1-Blend)         
        COLOR_DODGE = 7,           //Target / (1-Blend)         
        LINEAR_DODGE = 8,          //Target + Blend         
        OVERLAY = 9,               //(Target > 0.5) * (1 - (1-2*(Target-0.5)) * (1-Blend)) +(Target <= 0.5) * ((2*Target) * Blend)
        SOFT_LIGHT = 10,           //(Blend > 0.5) * (1 - (1-Target) * (1-(Blend-0.5))) +(Blend <= 0.5) * (Target * (Blend+0.5))
        HARD_LIGHT = 11,           //(Blend > 0.5) * (1 - (1-Target) * (1-2*(Blend-0.5))) +(Blend <= 0.5) * (Target * (2*Blend))
        VIVID_LIGHT = 12,          //(Blend > 0.5) * (1 - (1-Target) / (2*(Blend-0.5))) +(Blend <= 0.5) * (Target / (1-2*Blend))
        LINEAR_LIGHT = 13,         //(Blend > 0.5) * (Target + 2*(Blend-0.5)) +(Blend <= 0.5) * (Target + 2*Blend - 1)
        PIN_LIGHT = 14,            //(Blend > 0.5) * (max(Target,2*(Blend-0.5))) +(Blend <= 0.5) * (min(Target,2*Blend)))
        DIFFERENCE = 15,           //| Target - Blend |         
        EXCLUSION = 16,            //0.5 - 2*(Target-0.5)*(Blend-0.5)
        DIVIDE = 17                //Target/Blend
    };
    /** @17 Photoshop blending modes Inspired by GIMP and
    http://www.deepskycolors.com/archivo/2010/04/21/formulas-for-Photoshop-blending-modes.html.
    @param target and blend Input SAME_SIZE 8-bit 3-channel image.
    @param dst Output 8-bit 3-channel image.
    @param flags layerModelBlending algorithm : CV::DARKEN、CV::MULTIPY、CV::COLOR_BURN 、CV::LINEAR_BRUN
    、CV::LIGHTEN 、CV::SCREEN 、CV::COLOR_DODGE 、CV::LINEAR_DODGE 、CV::OVERLAY、CV::SOFT_LIGHT、CV::HARD_LIGHT、
    CV::VIVID_LIGHT、CV::LINEAR_LIGHT、CV::PIN_LIGHT、CV::DIFFERENCE、CV::EXCLUSION 、CV::DIVIDE 
    */
    CV_EXPORTS_W void layerModelBlending(InputArray targetInputArray blendOutputArray dstint flag=1);
    //! @} addtogroup layerModelBlending

    二个是添加layerModelBlending函数实体。
    /*M///////////////////////////////////////////////////////////////////////////////////////
    //
    //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
    //
    //  By downloading, copying, installing or using the software you agree to this license.
    //  If you do not agree to this license, do not download, install,
    //  copy or use the software.
    //
    //
    //                           License Agreement
    //                For Open Source Computer Vision Library
    //
    // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
    // Third party copyrights are property of their respective owners.
    //
    // Redistribution and use in source and binary forms, with or without modification,
    // are permitted provided that the following conditions are met:
    //
    //   * Redistribution's of source code must retain the above copyright notice,
    //     this list of conditions and the following disclaimer.
    //
    //   * Redistribution's in binary form must reproduce the above copyright notice,
    //     this list of conditions and the following disclaimer in the documentation
    //     and/or other materials provided with the distribution.
    //
    //   * The name of the copyright holders may not be used to endorse or promote products
    //     derived from this software without specific prior written permission.
    //
    // This software is provided by the copyright holders and contributors "as is" and
    // any express or implied warranties, including, but not limited to, the implied
    // warranties of merchantability and fitness for a particular purpose are disclaimed.
    // In no event shall the Intel Corporation or contributors be liable for any direct,
    // indirect, incidental, special, exemplary, or consequential damages
    // (including, but not limited to, procurement of substitute goods or services;
    // loss of use, data, or profits; or business interruption) however caused
    // and on any theory of liability, whether in contract, strict liability,
    // or tort (including negligence or otherwise) arising in any way out of
    // the use of this software, even if advised of the possibility of such damage.
    //
    //M*/


    #include "precomp.hpp"
    #include "opencv2/photo.hpp"

    using namespace std;
    using namespace cv;

    #define EPSILON      1e-6f

    #define SAFE_DIV_MIN EPSILON
    #define SAFE_DIV_MAX (1.0f / SAFE_DIV_MIN)

    #define    CLAMP(f,min,max)    ((f)<(min)?(min):(f)>(max)?(max):(f))

    namespace cv
    {

    /*  local function prototypes  */
    static inline float    safe_div(float a, float b);
    /* returns a / b, clamped to [-SAFE_DIV_MAX, SAFE_DIV_MAX].
     * if -SAFE_DIV_MIN <= a <= SAFE_DIV_MIN, returns 0.
     */

    static inline float safe_div(float a, float b)
    {
        float result = 0.0f;

        if (fabsf(a) > SAFE_DIV_MIN)
        {
            result = a / b;
            result = CLAMP(result, -SAFE_DIV_MAX, SAFE_DIV_MAX);
        }

        return result;
    }
    CV_EXPORTS_W void layerModelBlending(InputArray _target, InputArray _blend, OutputArray _dst, int flag)
    {
        Mat target = _target.getMat();
        Mat blend = _blend.getMat();
        Mat dst = _dst.getMat();

        for (int index_row = 0; index_row < target.rows; index_row++)
            for (int index_col = 0; index_col < target.cols; index_col++)
                for (int index_c = 0; index_c < 3; index_c++)
                    switch (flag)
                    {
                    case DARKEN:
                        dst.at<Vec3f>(index_row, index_col)[index_c] = min(
                            target.at<Vec3f>(index_row, index_col)[index_c],
                            blend.at<Vec3f>(index_row, index_col)[index_c]);
                        break;
                    case MULTIPY:
                        dst.at<Vec3f>(index_row, index_col)[index_c] =
                            target.at<Vec3f>(index_row, index_col)[index_c] *
                            blend.at<Vec3f>(index_row, index_col)[index_c];
                        break;
                    case COLOR_BURN:
                        dst.at<Vec3f>(index_row, index_col)[index_c] = 1 -
                            safe_div((1 - target.at<Vec3f>(index_row, index_col)[index_c]),
                                blend.at<Vec3f>(index_row, index_col)[index_c]);
                        break;
                    case LINEAR_BRUN:
                        dst.at<Vec3f>(index_row, index_col)[index_c] =
                            target.at<Vec3f>(index_row, index_col)[index_c] +
                            blend.at<Vec3f>(index_row, index_col)[index_c] - 1;
                        break;
                    case LIGHTEN:
                        dst.at<Vec3f>(index_row, index_col)[index_c] = max(
                            target.at<Vec3f>(index_row, index_col)[index_c],
                            blend.at<Vec3f>(index_row, index_col)[index_c]);
                        break;
                    case SCREEN:
                        dst.at<Vec3f>(index_row, index_col)[index_c] = 1 -
                            (1 - target.at<Vec3f>(index_row, index_col)[index_c]) *
                            (1 - blend.at<Vec3f>(index_row, index_col)[index_c]);
                        break;
                    case COLOR_DODGE:
                        dst.at<Vec3f>(index_row, index_col)[index_c] = safe_div
                        (target.at<Vec3f>(index_row, index_col)[index_c],
                            1 - blend.at<Vec3f>(index_row, index_col)[index_c]);
                        break;
                    case LINEAR_DODGE:
                        dst.at<Vec3f>(index_row, index_col)[index_c] =
                            target.at<Vec3f>(index_row, index_col)[index_c] +
                            blend.at<Vec3f>(index_row, index_col)[index_c];
                        break;
                    case OVERLAY:
                        if (target.at<Vec3f>(index_row, index_col)[index_c] > 0.5f)
                            dst.at<Vec3f>(index_row, index_col)[index_c] = 1 -
                            (1 - 2 * (target.at<Vec3f>(index_row, index_col)[index_c] - 0.5)) *
                            (1 - blend.at<Vec3f>(index_row, index_col)[index_c]);
                        else
                            dst.at<Vec3f>(index_row, index_col)[index_c] = 2 *
                            target.at<Vec3f>(index_row, index_col)[index_c] *
                            blend.at<Vec3f>(index_row, index_col)[index_c];
                        break;
                    case SOFT_LIGHT:
                        if (target.at<Vec3f>(index_row, index_col)[index_c] > 0.5f)
                            dst.at<Vec3f>(index_row, index_col)[index_c] = 1 -
                            (1 - target.at<Vec3f>(index_row, index_col)[index_c]) *
                            (1 - (blend.at<Vec3f>(index_row, index_col)[index_c] - 0.5));
                        else
                            dst.at<Vec3f>(index_row, index_col)[index_c] =
                            target.at<Vec3f>(index_row, index_col)[index_c] *
                            (blend.at<Vec3f>(index_row, index_col)[index_c] + 0.5);
                        break;
                    case HARD_LIGHT:
                        if (target.at<Vec3f>(index_row, index_col)[index_c] > 0.5f)
                            dst.at<Vec3f>(index_row, index_col)[index_c] = 1 -
                            (1 - target.at<Vec3f>(index_row, index_col)[index_c]) *
                            (1 - 2 * blend.at<Vec3f>(index_row, index_col)[index_c] - 0.5);
                        else
                            dst.at<Vec3f>(index_row, index_col)[index_c] =
                            target.at<Vec3f>(index_row, index_col)[index_c] *
                            (2 * blend.at<Vec3f>(index_row, index_col)[index_c]);
                        break;
                    case VIVID_LIGHT:
                        if (target.at<Vec3f>(index_row, index_col)[index_c] > 0.5f)
                            dst.at<Vec3f>(index_row, index_col)[index_c] = 1 -
                            safe_div(1 - target.at<Vec3f>(index_row, index_col)[index_c],
                            (2 * (blend.at<Vec3f>(index_row, index_col)[index_c] - 0.5)));
                        else
                            dst.at<Vec3f>(index_row, index_col)[index_c] =
                            safe_div(target.at<Vec3f>(index_row, index_col)[index_c],
                            (1 - 2 * blend.at<Vec3f>(index_row, index_col)[index_c]));
                        break;
                    case LINEAR_LIGHT:
                        if (target.at<Vec3f>(index_row, index_col)[index_c] > 0.5f)
                            dst.at<Vec3f>(index_row, index_col)[index_c] =
                            target.at<Vec3f>(index_row, index_col)[index_c] +
                            (2 * (blend.at<Vec3f>(index_row, index_col)[index_c] - 0.5));
                        else
                            dst.at<Vec3f>(index_row, index_col)[index_c] =
                            target.at<Vec3f>(index_row, index_col)[index_c] +
                            2 * blend.at<Vec3f>(index_row, index_col)[index_c] - 1;
                        break;
                    case PIN_LIGHT:
                        if (target.at<Vec3f>(index_row, index_col)[index_c] > 0.5f)
                            dst.at<Vec3f>(index_row, index_col)[index_c] =
                            max(target.at<Vec3f>(index_row, index_col)[index_c],
                            (float)(2 * (blend.at<Vec3f>(index_row, index_col)[index_c] - 0.5)));
                        else
                            dst.at<Vec3f>(index_row, index_col)[index_c] =
                            min(target.at<Vec3f>(index_row, index_col)[index_c],
                                2 * blend.at<Vec3f>(index_row, index_col)[index_c]);
                        break;
                    case DIFFERENCE:
                        dst.at<Vec3f>(index_row, index_col)[index_c] =
                            abs(target.at<Vec3f>(index_row, index_col)[index_c] -
                                blend.at<Vec3f>(index_row, index_col)[index_c]);
                        break;
                    case EXCLUSION:
                        dst.at<Vec3f>(index_row, index_col)[index_c] =
                            target.at<Vec3f>(index_row, index_col)[index_c] +
                            blend.at<Vec3f>(index_row, index_col)[index_c] -
                            2 * target.at<Vec3f>(index_row, index_col)[index_c] * blend.at<Vec3f>(index_row, index_col)[index_c];
                        break;
                    case DIVIDE:
                        dst.at<Vec3f>(index_row, index_col)[index_c] =
                            safe_div(target.at<Vec3f>(index_row, index_col)[index_c],
                                blend.at<Vec3f>(index_row, index_col)[index_c]);
                        break;
                    }
    }
    }
    由于有seamlessclone可以参考,所以这里很多东西,虽然繁琐、但是并不是没有解决方法。直到我发现在都设置正确的情况,总是出现link错误。我知道link错误是由于dll文件问题。
    经过研究发现:
    那么是缺少cv,添加之后。
     0000C793 1896 0767 ?layerModelBlending@@YAXVMat@cv@@00H@Z
     0000AEF7 2297 08F8 ?seamlessClone@cv@@YAXAEBV_InputArray@debug_build_guard@1@00V?
    你发现,我们缺少CV,通过添加namespcae、能够变成这样
     0000A209 1896 0767 ?layerModelBlending@cv@@YAXVMat@1@00H@Z
    再发现问题,通过修改形参,便成为:
    layerModelBlending@cv@@YAXAEBV_InputArray@debug_build_guard@1@0AEBV_OutputArray@31@H@Z
    调用成功。
    三、反思小结
    我在问题出现的地方卡了2天时间,直到去尝试寻找"dll文件结构查看器",才能够定位问题。
    使用"dll文件结构查看器"的能力我之前是不具备的,今后是会经常使用的。但是关键在于矛盾之中的思考,也就是处于矛盾情况下,不能一味地重复劳动,而是要跳出圈子,思考根本问题。这才是我记录本BLOG的关键。





  • 相关阅读:
    yii---模型的创建
    yii---控制器的创建
    yii的安装
    windows下安装composer
    wpgcms---列表页数据渲染
    Twig---基本使用
    wpgcms---详情页面数据怎么渲染
    Twig---的使用
    vue---指令怎么写
    vue---设置缩进为4个空格
  • 原文地址:https://www.cnblogs.com/jsxyhelu/p/12937077.html
Copyright © 2011-2022 走看看