在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 target, InputArray blend, OutputArray dst, int 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的关键。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jsxyhelu2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值