color.cpp 12.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*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) 2010-2012, Institute Of Software Chinese Academy Of Science, all rights reserved.
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
//    Wang Weiyan, wangweiyanster@gmail.com
19
//    Peng Xiao, pengxiao@multicorewareinc.com
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
//
// 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 oclMaterials 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"

using namespace cv;
using namespace cv::ocl;

#ifndef CV_DESCALE
#define CV_DESCALE(x, n) (((x) + (1 << ((n)-1))) >> (n))
#endif

#ifndef FLT_EPSILON
#define FLT_EPSILON     1.192092896e-07F
#endif

namespace cv
{
62 63 64 65
namespace ocl
{
extern const char *cvt_color;
}
66 67 68 69
}

namespace
{
70 71
void RGB2Gray_caller(const oclMat &src, oclMat &dst, int bidx)
{
72
    std::vector<std::pair<size_t , const void *> > args;
73 74 75 76
    int channels = src.oclchannels();
    char build_options[50];
    sprintf(build_options, "-D DEPTH_%d", src.depth());
    //printf("depth:%d,channels:%d,bidx:%d\n",src.depth(),src.oclchannels(),bidx);
77 78 79 80 81 82 83 84
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.cols));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.rows));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&channels));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&bidx));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data));
85 86 87 88 89
    size_t gt[3] = {src.cols, src.rows, 1}, lt[3] = {16, 16, 1};
    openCLExecuteKernel(src.clCxt, &cvt_color, "RGB2Gray", gt, lt, args, -1, -1, build_options);
}
void Gray2RGB_caller(const oclMat &src, oclMat &dst)
{
90
    std::vector<std::pair<size_t , const void *> > args;
91 92 93
    char build_options[50];
    sprintf(build_options, "-D DEPTH_%d", src.depth());
    //printf("depth:%d,channels:%d,bidx:%d\n",src.depth(),src.oclchannels(),bidx);
94 95 96 97 98 99
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.cols));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.rows));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.step));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data));
100 101 102 103 104
    size_t gt[3] = {src.cols, src.rows, 1}, lt[3] = {16, 16, 1};
    openCLExecuteKernel(src.clCxt, &cvt_color, "Gray2RGB", gt, lt, args, -1, -1, build_options);
}
void RGB2YUV_caller(const oclMat &src, oclMat &dst, int bidx)
{
105
    std::vector<std::pair<size_t , const void *> > args;
106 107 108 109
    int channels = src.oclchannels();
    char build_options[50];
    sprintf(build_options, "-D DEPTH_%d", src.depth());
    //printf("depth:%d,channels:%d,bidx:%d\n",src.depth(),src.oclchannels(),bidx);
110 111 112 113 114 115 116 117
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.cols));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.rows));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&channels));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&bidx));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data));
118 119 120 121 122
    size_t gt[3] = {src.cols, src.rows, 1}, lt[3] = {16, 16, 1};
    openCLExecuteKernel(src.clCxt, &cvt_color, "RGB2YUV", gt, lt, args, -1, -1, build_options);
}
void YUV2RGB_caller(const oclMat &src, oclMat &dst, int bidx)
{
123
    std::vector<std::pair<size_t , const void *> > args;
124 125 126 127
    int channels = src.oclchannels();
    char build_options[50];
    sprintf(build_options, "-D DEPTH_%d", src.depth());
    //printf("depth:%d,channels:%d,bidx:%d\n",src.depth(),src.oclchannels(),bidx);
128 129 130 131 132 133 134 135
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.cols));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.rows));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&channels));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&bidx));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data));
136 137 138 139 140
    size_t gt[3] = {src.cols, src.rows, 1}, lt[3] = {16, 16, 1};
    openCLExecuteKernel(src.clCxt, &cvt_color, "YUV2RGB", gt, lt, args, -1, -1, build_options);
}
void YUV2RGB_NV12_caller(const oclMat &src, oclMat &dst, int bidx)
{
141
    std::vector<std::pair<size_t , const void *> > args;
142 143 144
    char build_options[50];
    sprintf(build_options, "-D DEPTH_%d", src.depth());
    //printf("depth:%d,channels:%d,bidx:%d\n",src.depth(),src.oclchannels(),bidx);
145 146 147 148 149 150 151 152 153
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.cols));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.rows));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&bidx));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.cols));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.rows));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data));
154 155 156 157 158
    size_t gt[3] = {dst.cols / 2, dst.rows / 2, 1}, lt[3] = {16, 16, 1};
    openCLExecuteKernel(src.clCxt, &cvt_color, "YUV2RGBA_NV12", gt, lt, args, -1, -1, build_options);
}
void RGB2YCrCb_caller(const oclMat &src, oclMat &dst, int bidx)
{
159
    std::vector<std::pair<size_t , const void *> > args;
160 161 162 163
    int channels = src.oclchannels();
    char build_options[50];
    sprintf(build_options, "-D DEPTH_%d", src.depth());
    //printf("depth:%d,channels:%d,bidx:%d\n",src.depth(),src.oclchannels(),bidx);
164 165 166 167 168 169 170 171
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.cols));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.rows));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.step));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&channels));
    args.push_back( std::make_pair( sizeof(cl_int) , (void *)&bidx));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data));
    args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data));
172 173 174 175 176 177 178
    size_t gt[3] = {src.cols, src.rows, 1}, lt[3] = {16, 16, 1};
    openCLExecuteKernel(src.clCxt, &cvt_color, "RGB2YCrCb", gt, lt, args, -1, -1, build_options);
}
void cvtColor_caller(const oclMat &src, oclMat &dst, int code, int dcn)
{
    Size sz = src.size();
    int scn = src.oclchannels(), depth = src.depth(), bidx;
179

180
    CV_Assert(depth == CV_8U || depth == CV_16U || depth == CV_32F);
181

182 183
    switch (code)
    {
184
        /*
185 186 187 188 189 190
        case COLOR_BGR2BGRA: case COLOR_RGB2BGRA: case COLOR_BGRA2BGR:
        case COLOR_RGBA2BGR: case COLOR_RGB2BGR: case COLOR_BGRA2RGBA:
        case COLOR_BGR2BGR565: case COLOR_BGR2BGR555: case COLOR_RGB2BGR565: case COLOR_RGB2BGR555:
        case COLOR_BGRA2BGR565: case COLOR_BGRA2BGR555: case COLOR_RGBA2BGR565: case COLOR_RGBA2BGR555:
        case COLOR_BGR5652BGR: case COLOR_BGR5552BGR: case COLOR_BGR5652RGB: case COLOR_BGR5552RGB:
        case COLOR_BGR5652BGRA: case COLOR_BGR5552BGRA: case COLOR_BGR5652RGBA: case COLOR_BGR5552RGBA:
191
        */
192 193 194 195
    case COLOR_BGR2GRAY:
    case COLOR_BGRA2GRAY:
    case COLOR_RGB2GRAY:
    case COLOR_RGBA2GRAY:
196 197
    {
        CV_Assert(scn == 3 || scn == 4);
198
        bidx = code == COLOR_BGR2GRAY || code == COLOR_BGRA2GRAY ? 0 : 2;
199 200 201 202
        dst.create(sz, CV_MAKETYPE(depth, 1));
        RGB2Gray_caller(src, dst, bidx);
        break;
    }
203 204
    case COLOR_GRAY2BGR:
    case COLOR_GRAY2BGRA:
205 206
    {
        CV_Assert(scn == 1);
207
        dcn  = code == COLOR_GRAY2BGRA ? 4 : 3;
208 209 210 211
        dst.create(sz, CV_MAKETYPE(depth, dcn));
        Gray2RGB_caller(src, dst);
        break;
    }
212 213
    case COLOR_BGR2YUV:
    case COLOR_RGB2YUV:
214 215
    {
        CV_Assert(scn == 3 || scn == 4);
216
        bidx = code == COLOR_BGR2YUV ? 0 : 2;
217 218 219 220
        dst.create(sz, CV_MAKETYPE(depth, 3));
        RGB2YUV_caller(src, dst, bidx);
        break;
    }
221 222
    case COLOR_YUV2BGR:
    case COLOR_YUV2RGB:
223 224
    {
        CV_Assert(scn == 3 || scn == 4);
225
        bidx = code == COLOR_YUV2BGR ? 0 : 2;
226 227 228
        dst.create(sz, CV_MAKETYPE(depth, 3));
        YUV2RGB_caller(src, dst, bidx);
        break;
229
    }
230 231 232 233
    case COLOR_YUV2RGB_NV12:
    case COLOR_YUV2BGR_NV12:
    case COLOR_YUV2RGBA_NV12:
    case COLOR_YUV2BGRA_NV12:
234 235 236
    {
        CV_Assert(scn == 1);
        CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U );
237 238
        dcn  = code == COLOR_YUV2BGRA_NV12 || code == COLOR_YUV2RGBA_NV12 ? 4 : 3;
        bidx = code == COLOR_YUV2BGRA_NV12 || code == COLOR_YUV2BGR_NV12 ? 0 : 2;
239 240 241 242 243 244

        Size dstSz(sz.width, sz.height * 2 / 3);
        dst.create(dstSz, CV_MAKETYPE(depth, dcn));
        YUV2RGB_NV12_caller(src, dst, bidx);
        break;
    }
245 246
    case COLOR_BGR2YCrCb:
    case COLOR_RGB2YCrCb:
247 248
    {
        CV_Assert(scn == 3 || scn == 4);
249
        bidx = code == COLOR_BGR2YCrCb ? 0 : 2;
250 251 252 253
        dst.create(sz, CV_MAKETYPE(depth, 3));
        RGB2YCrCb_caller(src, dst, bidx);
        break;
    }
254 255
    case COLOR_YCrCb2BGR:
    case COLOR_YCrCb2RGB:
256 257 258 259
    {
        break;
    }
    /*
260 261 262 263 264 265 266 267 268
    case COLOR_BGR5652GRAY: case COLOR_BGR5552GRAY:
    case COLOR_GRAY2BGR565: case COLOR_GRAY2BGR555:
    case COLOR_BGR2YCrCb: case COLOR_RGB2YCrCb:
    case COLOR_BGR2XYZ: case COLOR_RGB2XYZ:
    case COLOR_XYZ2BGR: case COLOR_XYZ2RGB:
    case COLOR_BGR2HSV: case COLOR_RGB2HSV: case COLOR_BGR2HSV_FULL: case COLOR_RGB2HSV_FULL:
    case COLOR_BGR2HLS: case COLOR_RGB2HLS: case COLOR_BGR2HLS_FULL: case COLOR_RGB2HLS_FULL:
    case COLOR_HSV2BGR: case COLOR_HSV2RGB: case COLOR_HSV2BGR_FULL: case COLOR_HSV2RGB_FULL:
    case COLOR_HLS2BGR: case COLOR_HLS2RGB: case COLOR_HLS2BGR_FULL: case COLOR_HLS2RGB_FULL:
269 270
    */
    default:
271
        CV_Error(Error::StsBadFlag, "Unknown/unsupported color conversion code" );
272 273
    }
}
274 275 276 277 278 279
}

void cv::ocl::cvtColor(const oclMat &src, oclMat &dst, int code, int dcn)
{
    cvtColor_caller(src, dst, code, dcn);
}