/
githubmirror
/
incubator-mxnet
Обзор
Документация
Войти
/
githubmirror
/
incubator-mxnet
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
plugin/opencv/cv_api.cc
189 строк
7 KB
mozga
[master][clang-format] Re-format cc. .h. .cu files; cond. (#20704)
19 ноя 2021, 11:27
Не верифицирован
19 ноя 2021, 11:27
1add250
Код
Авторство
О чём код?
/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /*! * \file cv_api.h * \brief C API for opencv * \author Junyuan Xie */ #include <dmlc/base.h> #include <mxnet/base.h> #include <mxnet/ndarray.h> #include <opencv2/opencv.hpp> #include "cv_api.h" #include "../../src/c_api/c_api_common.h" using namespace mxnet; // http://www.64lines.com/jpeg-width-height // Gets the JPEG size from the array of data passed to the function, file reference: // http://www.obrador.com/essentialjpeg/headerinfo.htm bool get_jpeg_size(const unsigned char* data, mx_uint data_size, mx_uint* width, mx_uint* height) { // Check for valid JPEG image mx_uint i = 0; // Keeps track of the position within the file if (data[i] == 0xFF && data[i + 1] == 0xD8 && data[i + 2] == 0xFF && data[i + 3] == 0xE0) { i += 4; // Check for valid JPEG header (null terminated JFIF) if (data[i + 2] == 'J' && data[i + 3] == 'F' && data[i + 4] == 'I' && data[i + 5] == 'F' && data[i + 6] == 0x00) { // Retrieve the block length of the first block since // the first block will not contain the size of file uint16_t block_length = data[i] * 256 + data[i + 1]; while (i < data_size) { i += block_length; // Increase the file index to get to the next block if (i >= data_size) return false; // Check to protect against segmentation faults if (data[i] != 0xFF) return false; // Check that we are truly at the start of another block if (data[i + 1] == 0xC0) { // 0xFFC0 is the "Start of frame" marker which contains the file size // The structure of the 0xFFC0 block is quite simple // [0xFFC0][ushort length][uchar precision][ushort x][ushort y] *height = data[i + 5] * 256 + data[i + 6]; *width = data[i + 7] * 256 + data[i + 8]; return true; } else { i += 2; // Skip the block marker block_length = data[i] * 256 + data[i + 1]; // Go to the next block } } return false; // If this point is reached then no size was found } else { return false; // Not a valid JFIF string } } else { return false; // Not a valid SOI header } } bool get_png_size(const unsigned char* data, mx_uint data_size, mx_uint* width, mx_uint* height) { if (data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47) { unsigned char const* p = data + 16; *width = ((p[0] * 256 + p[1]) * 256 + p[2]) * 256 + p[3]; p += 4; *height = ((p[0] * 256 + p[1]) * 256 + p[2]) * 256 + p[3]; return true; } else { return false; } } MXNET_DLL int MXCVImdecode(const unsigned char* img, const mx_uint len, const int flag, NDArrayHandle* out) { API_BEGIN(); mx_uint dims[3]; CHECK_GE(flag, 0) << "flag must be 0 (grayscale) or 1 (colored)."; dims[2] = flag == 0 ? 1 : 3; if (get_jpeg_size(img, len, dims + 1, dims)) { } else if (get_png_size(img, len, dims + 1, dims)) { } else { LOG(FATAL) << "Only supports png and jpg."; } NDArray ndout(mxnet::TShape(dims, dims + 3), Context::CPU(), true, mshadow::kUint8); unsigned char* img_cpy = new unsigned char[len]; memcpy(img_cpy, img, sizeof(unsigned char) * len); Engine::Get()->PushSync( [=](RunContext ctx) { ndout.CheckAndAlloc(); cv::Mat buf(1, len, CV_8U, img_cpy); cv::Mat dst(dims[0], dims[1], flag == 0 ? CV_8U : CV_8UC3, ndout.data().dptr_); #if (CV_MAJOR_VERSION > 3 || (CV_MAJOR_VERSION == 3 && CV_MINOR_VERSION >= 3)) cv::imdecode(buf, flag | cv::IMREAD_IGNORE_ORIENTATION, &dst); #else cv::imdecode(buf, flag, &dst); #endif CHECK(!dst.empty()); delete[] img_cpy; }, ndout.ctx(), {}, {ndout.var()}); NDArray* tmp = new NDArray(); *tmp = ndout; *out = tmp; API_END(); } MXNET_DLL int MXCVResize(NDArrayHandle src, const mx_uint w, const mx_uint h, const int interpolation, NDArrayHandle* out) { API_BEGIN(); NDArray ndsrc = *static_cast<NDArray*>(src); CHECK_EQ(ndsrc.shape().ndim(), 3); CHECK_EQ(ndsrc.ctx(), Context::CPU()); CHECK_EQ(ndsrc.dtype(), mshadow::kUint8); mx_uint dims[3] = {h, w, ndsrc.shape()[2]}; NDArray ndout(mxnet::TShape(dims, dims + 3), Context::CPU(), true, mshadow::kUint8); Engine::Get()->PushSync( [=](RunContext ctx) { ndout.CheckAndAlloc(); cv::Mat buf( ndsrc.shape()[0], ndsrc.shape()[1], dims[2] == 3 ? CV_8UC3 : CV_8U, ndsrc.data().dptr_); cv::Mat dst(h, w, dims[2] == 3 ? CV_8UC3 : CV_8U, ndout.data().dptr_); cv::resize(buf, dst, cv::Size(w, h), 0, 0, interpolation); CHECK(!dst.empty()); }, ndout.ctx(), {ndsrc.var()}, {ndout.var()}); NDArray* tmp = new NDArray(); *tmp = ndout; *out = tmp; API_END(); } MXNET_DLL int MXCVcopyMakeBorder(NDArrayHandle src, const int top, const int bot, const int left, const int right, const int type, const double value, NDArrayHandle* out) { API_BEGIN(); NDArray ndsrc = *static_cast<NDArray*>(src); CHECK_EQ(ndsrc.shape().ndim(), 3); CHECK_EQ(ndsrc.ctx(), Context::CPU()); CHECK_EQ(ndsrc.dtype(), mshadow::kUint8); int h = ndsrc.shape()[0], w = ndsrc.shape()[1], c = ndsrc.shape()[2]; mx_uint dims[3] = {top + h + bot, left + w + right, c}; NDArray ndout(mxnet::TShape(dims, dims + 3), Context::CPU(), true, mshadow::kUint8); Engine::Get()->PushSync( [=](RunContext ctx) { ndout.CheckAndAlloc(); cv::Mat buf(h, w, c == 3 ? CV_8UC3 : CV_8U, ndsrc.data().dptr_); cv::Mat dst(top + h + bot, left + w + right, c == 3 ? CV_8UC3 : CV_8U, ndout.data().dptr_); cv::copyMakeBorder(buf, dst, top, bot, left, right, type, cv::Scalar(value)); CHECK(!dst.empty()); }, ndout.ctx(), {ndsrc.var()}, {ndout.var()}); NDArray* tmp = new NDArray(); *tmp = ndout; *out = tmp; API_END(); }