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的关键。





  • 相关阅读:
    python Database Poll for SQL SERVER
    SQLAlchemy表操作和增删改查
    flask动态url规则
    flask配置管理
    一个Flask运行分析
    Function Set in OPEN CASCADE
    Happy New Year 2016
    Apply Newton Method to Find Extrema in OPEN CASCADE
    OPEN CASCADE Multiple Variable Function
    OPEN CASCADE Gauss Least Square
  • 原文地址:https://www.cnblogs.com/jsxyhelu/p/12937077.html
Copyright © 2011-2022 走看看