Path: blob/master/modules/stitching/src/opencl/multibandblend.cl
16337 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html.3//4// Copyright (C) 2014, Itseez, Inc, all rights reserved.56//7// Common preprocessors macro8//910//11// TODO: Move this common code into "header" file12//1314#ifndef NL // New Line: for preprocessor debugging15#define NL16#endif1718#define REF(x) x19#define __CAT(x, y) x##y20#define CAT(x, y) __CAT(x, y)2122//23// All matrixes are come with this description ("name" is a name of matrix):24// * name_CN - number of channels (1,2,3,4)25// * name_DEPTH - numeric value of CV_MAT_DEPTH(type). See CV_8U, CV_32S, etc macro below.26//27// Currently we also pass these attributes (to reduce this macro block):28// * name_T - datatype (int, float, uchar4, float4)29// * name_T1 - datatype for one channel (int, float, uchar).30// It is equal to result of "T1(name_T)" macro31// * name_TSIZE - CV_ELEM_SIZE(type).32// We can't use sizeof(name_T) here, because sizeof(float3) is usually equal to 8, not 6.33// * name_T1SIZE - CV_ELEM_SIZE1(type)34//3536//37// Usage sample:38//39// #define workType TYPE(float, src_CN)40// #define convertToWorkType CONVERT_TO(workType)41// #define convertWorkTypeToDstType CONVERT(workType, dst_T)42//43// __kernel void kernelFn(DECLARE_MAT_ARG(src), DECLARE_MAT_ARG(dst))44// {45// const int x = get_global_id(0);46// const int y = get_global_id(1);47//48// if (x < srcWidth && y < srcHeight)49// {50// int src_byteOffset = MAT_BYTE_OFFSET(src, x, y);51// int dst_byteOffset = MAT_BYTE_OFFSET(dst, x, y);52// workType value = convertToWorkType(LOAD_MAT_AT(src, src_byteOffset));53//54// ... value processing ...55//56// STORE_MAT_AT(dst, dst_byteOffset, convertWorkTypeToDstType(value));57// }58// }59//6061#define DECLARE_MAT_ARG(name) \62__global uchar* restrict name ## Ptr, \63int name ## StepBytes, \64int name ## Offset, \65int name ## Height, \66int name ## Width NL6768#define MAT_BYTE_OFFSET(name, x, y) mad24((y)/* + name ## OffsetY*/, name ## StepBytes, ((x)/* + name ## OffsetX*/) * (int)(name ## _TSIZE) + name ## Offset)69#define MAT_RELATIVE_BYTE_OFFSET(name, x, y) mad24(y, name ## StepBytes, (x) * (int)(name ## _TSIZE))7071#define __LOAD_MAT_AT(name, byteOffset) *((const __global name ## _T*)(name ## Ptr + (byteOffset)))72#define __vload_CN__(name_cn) vload ## name_cn73#define __vload_CN_(name_cn) __vload_CN__(name_cn)74#define __vload_CN(name) __vload_CN_(name ## _CN)75#define __LOAD_MAT_AT_vload(name, byteOffset) __vload_CN(name)(0, ((const __global name ## _T1*)(name ## Ptr + (byteOffset))))76#define __LOAD_MAT_AT_1 __LOAD_MAT_AT77#define __LOAD_MAT_AT_2 __LOAD_MAT_AT78#define __LOAD_MAT_AT_3 __LOAD_MAT_AT_vload79#define __LOAD_MAT_AT_4 __LOAD_MAT_AT80#define __LOAD_MAT_AT_CN__(name_cn) __LOAD_MAT_AT_ ## name_cn81#define __LOAD_MAT_AT_CN_(name_cn) __LOAD_MAT_AT_CN__(name_cn)82#define __LOAD_MAT_AT_CN(name) __LOAD_MAT_AT_CN_(name ## _CN)83#define LOAD_MAT_AT(name, byteOffset) __LOAD_MAT_AT_CN(name)(name, byteOffset)8485#define __STORE_MAT_AT(name, byteOffset, v) *((__global name ## _T*)(name ## Ptr + (byteOffset))) = v86#define __vstore_CN__(name_cn) vstore ## name_cn87#define __vstore_CN_(name_cn) __vstore_CN__(name_cn)88#define __vstore_CN(name) __vstore_CN_(name ## _CN)89#define __STORE_MAT_AT_vstore(name, byteOffset, v) __vstore_CN(name)(v, 0, ((__global name ## _T1*)(name ## Ptr + (byteOffset))))90#define __STORE_MAT_AT_1 __STORE_MAT_AT91#define __STORE_MAT_AT_2 __STORE_MAT_AT92#define __STORE_MAT_AT_3 __STORE_MAT_AT_vstore93#define __STORE_MAT_AT_4 __STORE_MAT_AT94#define __STORE_MAT_AT_CN__(name_cn) __STORE_MAT_AT_ ## name_cn95#define __STORE_MAT_AT_CN_(name_cn) __STORE_MAT_AT_CN__(name_cn)96#define __STORE_MAT_AT_CN(name) __STORE_MAT_AT_CN_(name ## _CN)97#define STORE_MAT_AT(name, byteOffset, v) __STORE_MAT_AT_CN(name)(name, byteOffset, v)9899#define T1_uchar uchar100#define T1_uchar2 uchar101#define T1_uchar3 uchar102#define T1_uchar4 uchar103#define T1_char char104#define T1_char2 char105#define T1_char3 char106#define T1_char4 char107#define T1_ushort ushort108#define T1_ushort2 ushort109#define T1_ushort3 ushort110#define T1_ushort4 ushort111#define T1_short short112#define T1_short2 short113#define T1_short3 short114#define T1_short4 short115#define T1_int int116#define T1_int2 int117#define T1_int3 int118#define T1_int4 int119#define T1_float float120#define T1_float2 float121#define T1_float3 float122#define T1_float4 float123#define T1_double double124#define T1_double2 double125#define T1_double3 double126#define T1_double4 double127#define T1(type) REF(CAT(T1_, REF(type)))128129#define uchar1 uchar130#define char1 char131#define short1 short132#define ushort1 ushort133#define int1 int134#define float1 float135#define double1 double136#define TYPE(type, cn) REF(CAT(REF(type), REF(cn)))137138#define __CONVERT_MODE_uchar_uchar __NO_CONVERT139#define __CONVERT_MODE_uchar_char __CONVERT_sat140#define __CONVERT_MODE_uchar_ushort __CONVERT141#define __CONVERT_MODE_uchar_short __CONVERT142#define __CONVERT_MODE_uchar_int __CONVERT143#define __CONVERT_MODE_uchar_float __CONVERT144#define __CONVERT_MODE_uchar_double __CONVERT145#define __CONVERT_MODE_char_uchar __CONVERT_sat146#define __CONVERT_MODE_char_char __NO_CONVERT147#define __CONVERT_MODE_char_ushort __CONVERT_sat148#define __CONVERT_MODE_char_short __CONVERT149#define __CONVERT_MODE_char_int __CONVERT150#define __CONVERT_MODE_char_float __CONVERT151#define __CONVERT_MODE_char_double __CONVERT152#define __CONVERT_MODE_ushort_uchar __CONVERT_sat153#define __CONVERT_MODE_ushort_char __CONVERT_sat154#define __CONVERT_MODE_ushort_ushort __NO_CONVERT155#define __CONVERT_MODE_ushort_short __CONVERT_sat156#define __CONVERT_MODE_ushort_int __CONVERT157#define __CONVERT_MODE_ushort_float __CONVERT158#define __CONVERT_MODE_ushort_double __CONVERT159#define __CONVERT_MODE_short_uchar __CONVERT_sat160#define __CONVERT_MODE_short_char __CONVERT_sat161#define __CONVERT_MODE_short_ushort __CONVERT_sat162#define __CONVERT_MODE_short_short __NO_CONVERT163#define __CONVERT_MODE_short_int __CONVERT164#define __CONVERT_MODE_short_float __CONVERT165#define __CONVERT_MODE_short_double __CONVERT166#define __CONVERT_MODE_int_uchar __CONVERT_sat167#define __CONVERT_MODE_int_char __CONVERT_sat168#define __CONVERT_MODE_int_ushort __CONVERT_sat169#define __CONVERT_MODE_int_short __CONVERT_sat170#define __CONVERT_MODE_int_int __NO_CONVERT171#define __CONVERT_MODE_int_float __CONVERT172#define __CONVERT_MODE_int_double __CONVERT173#define __CONVERT_MODE_float_uchar __CONVERT_sat_rte174#define __CONVERT_MODE_float_char __CONVERT_sat_rte175#define __CONVERT_MODE_float_ushort __CONVERT_sat_rte176#define __CONVERT_MODE_float_short __CONVERT_sat_rte177#define __CONVERT_MODE_float_int __CONVERT_rte178#define __CONVERT_MODE_float_float __NO_CONVERT179#define __CONVERT_MODE_float_double __CONVERT180#define __CONVERT_MODE_double_uchar __CONVERT_sat_rte181#define __CONVERT_MODE_double_char __CONVERT_sat_rte182#define __CONVERT_MODE_double_ushort __CONVERT_sat_rte183#define __CONVERT_MODE_double_short __CONVERT_sat_rte184#define __CONVERT_MODE_double_int __CONVERT_rte185#define __CONVERT_MODE_double_float __CONVERT186#define __CONVERT_MODE_double_double __NO_CONVERT187#define __CONVERT_MODE(srcType, dstType) CAT(__CONVERT_MODE_, CAT(REF(T1(srcType)), CAT(_, REF(T1(dstType)))))188189#define __ROUND_MODE__NO_CONVERT190#define __ROUND_MODE__CONVERT // nothing191#define __ROUND_MODE__CONVERT_rte _rte192#define __ROUND_MODE__CONVERT_sat _sat193#define __ROUND_MODE__CONVERT_sat_rte _sat_rte194#define ROUND_MODE(srcType, dstType) CAT(__ROUND_MODE_, __CONVERT_MODE(srcType, dstType))195196#define __CONVERT_ROUND(dstType, roundMode) CAT(CAT(convert_, REF(dstType)), roundMode)197#define __NO_CONVERT(dstType) // nothing198#define __CONVERT(dstType) __CONVERT_ROUND(dstType,)199#define __CONVERT_rte(dstType) __CONVERT_ROUND(dstType,_rte)200#define __CONVERT_sat(dstType) __CONVERT_ROUND(dstType,_sat)201#define __CONVERT_sat_rte(dstType) __CONVERT_ROUND(dstType,_sat_rte)202#define CONVERT(srcType, dstType) REF(__CONVERT_MODE(srcType,dstType))(dstType)203#define CONVERT_TO(dstType) __CONVERT_ROUND(dstType,)204205// OpenCV depths206#define CV_8U 0207#define CV_8S 1208#define CV_16U 2209#define CV_16S 3210#define CV_32S 4211#define CV_32F 5212#define CV_64F 6213214//215// End of common preprocessors macro216//217218219220#if defined(DEFINE_feed)221222#define workType TYPE(weight_T1, src_CN)223224#if src_DEPTH == 3 && src_CN == 3225#define convertSrcToWorkType convert_float3226#else227#define convertSrcToWorkType CONVERT_TO(workType)228#endif229230#if dst_DEPTH == 3 && dst_CN == 3231#define convertToDstType convert_short3232#else233#define convertToDstType CONVERT_TO(dst_T) // sat_rte provides incompatible results with CPU path234#endif235236__kernel void feed(237DECLARE_MAT_ARG(src), DECLARE_MAT_ARG(weight),238DECLARE_MAT_ARG(dst), DECLARE_MAT_ARG(dstWeight)239)240{241const int x = get_global_id(0);242const int y = get_global_id(1);243244if (x < srcWidth && y < srcHeight)245{246int src_byteOffset = MAT_BYTE_OFFSET(src, x, y);247int weight_byteOffset = MAT_BYTE_OFFSET(weight, x, y);248int dst_byteOffset = MAT_BYTE_OFFSET(dst, x, y);249int dstWeight_byteOffset = MAT_BYTE_OFFSET(dstWeight, x, y);250251weight_T w = LOAD_MAT_AT(weight, weight_byteOffset);252workType src_value = convertSrcToWorkType(LOAD_MAT_AT(src, src_byteOffset));253STORE_MAT_AT(dst, dst_byteOffset, LOAD_MAT_AT(dst, dst_byteOffset) + convertToDstType(src_value * w));254STORE_MAT_AT(dstWeight, dstWeight_byteOffset, LOAD_MAT_AT(dstWeight, dstWeight_byteOffset) + w);255}256}257258#endif259260#if defined(DEFINE_normalizeUsingWeightMap)261262#if mat_DEPTH == 3 && mat_CN == 3263#define workType float3264#define convertSrcToWorkType convert_float3265#define convertToDstType convert_short3266#else267#define workType TYPE(weight_T1, mat_CN)268#define convertSrcToWorkType CONVERT_TO(workType)269#define convertToDstType CONVERT_TO(mat_T) // sat_rte provides incompatible results with CPU path270#endif271272#if weight_DEPTH >= CV_32F273#define WEIGHT_EPS 1e-5f274#else275#define WEIGHT_EPS 0276#endif277278__kernel void normalizeUsingWeightMap(279DECLARE_MAT_ARG(mat), DECLARE_MAT_ARG(weight)280)281{282const int x = get_global_id(0);283const int y = get_global_id(1);284285if (x < matWidth && y < matHeight)286{287int mat_byteOffset = MAT_BYTE_OFFSET(mat, x, y);288int weight_byteOffset = MAT_BYTE_OFFSET(weight, x, y);289290weight_T w = LOAD_MAT_AT(weight, weight_byteOffset);291workType value = convertSrcToWorkType(LOAD_MAT_AT(mat, mat_byteOffset));292value = value / (w + WEIGHT_EPS);293STORE_MAT_AT(mat, mat_byteOffset, convertToDstType(value));294}295}296297#endif298299300