vendor: OpenCV 5.0.0 snapshot at 755e50675d97db9b7d449d8bd6b09888646f6c6e
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
class DefaultAllocator : public cv::cann::AscendMat::Allocator
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<uchar> allocate(size_t size) CV_OVERRIDE;
|
||||
bool allocate(cv::cann::AscendMat* mat, int rows, int cols, size_t elemSize) CV_OVERRIDE;
|
||||
};
|
||||
|
||||
std::shared_ptr<uchar> DefaultAllocator::allocate(size_t size)
|
||||
{
|
||||
uchar* data;
|
||||
cv::cann::aclrtMallocWarpper((void**)(&data), size);
|
||||
return std::shared_ptr<uchar>(data, [](void* ptr) { cv::cann::aclrtFreeWarpper(ptr); });
|
||||
}
|
||||
|
||||
bool DefaultAllocator::allocate(cv::cann::AscendMat* mat, int rows, int cols, size_t elemSize)
|
||||
{
|
||||
size_t totalBytes = elemSize * cols * rows;
|
||||
|
||||
// align by 32B.
|
||||
totalBytes = ((totalBytes + 32) & ~31);
|
||||
mat->data = allocate(totalBytes);
|
||||
mat->step = cols * elemSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DefaultAllocator cannDefaultAllocator;
|
||||
cv::cann::AscendMat::Allocator* g_defaultAllocator = &cannDefaultAllocator;
|
||||
} // namespace
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace cann
|
||||
{
|
||||
AscendMat::Allocator* AscendMat::defaultAllocator() { return g_defaultAllocator; }
|
||||
|
||||
void AscendMat::setDefaultAllocator(AscendMat::Allocator* allocator)
|
||||
{
|
||||
CV_Assert(allocator != 0);
|
||||
g_defaultAllocator = allocator;
|
||||
}
|
||||
|
||||
// TODO: this function is copied from matrix.cpp, which is a local symbol there and can not
|
||||
// be refreneced, consider optimizing.
|
||||
static int updateContinuityFlag(int flags, int dims, const int* size, const size_t* step)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < dims; i++)
|
||||
{
|
||||
if (size[i] > 1)
|
||||
break;
|
||||
}
|
||||
|
||||
uint64 t = (uint64)size[std::min(i, dims - 1)] * CV_MAT_CN(flags);
|
||||
for (j = dims - 1; j > i; j--)
|
||||
{
|
||||
t *= size[j];
|
||||
if (step[j] * size[j] < step[j - 1])
|
||||
break;
|
||||
}
|
||||
|
||||
if (j <= i && t == (uint64)(int)t)
|
||||
return flags | Mat::CONTINUOUS_FLAG;
|
||||
return flags & ~Mat::CONTINUOUS_FLAG;
|
||||
}
|
||||
|
||||
void AscendMat::updateContinuityFlag()
|
||||
{
|
||||
int sz[] = {rows, cols};
|
||||
size_t steps[] = {step, elemSize()};
|
||||
flags = cv::cann::updateContinuityFlag(flags, 2, sz, steps);
|
||||
}
|
||||
|
||||
void AscendMat::create(int _rows, int _cols, int _type)
|
||||
{
|
||||
CV_DbgAssert(_rows >= 0 && _cols >= 0);
|
||||
|
||||
_type &= Mat::TYPE_MASK;
|
||||
|
||||
if (rows == _rows && cols == _cols && type() == _type && data)
|
||||
return;
|
||||
|
||||
if (_rows > 0 && _cols > 0)
|
||||
{
|
||||
flags = Mat::MAGIC_VAL + _type;
|
||||
rows = _rows;
|
||||
cols = _cols;
|
||||
|
||||
const size_t esz = elemSize();
|
||||
|
||||
bool allocSuccess = allocator->allocate(this, rows, cols, esz);
|
||||
|
||||
if (!allocSuccess)
|
||||
{
|
||||
// custom allocator fails, try default allocator
|
||||
allocator = defaultAllocator();
|
||||
allocSuccess = allocator->allocate(this, rows, cols, esz);
|
||||
CV_Assert(allocSuccess);
|
||||
}
|
||||
|
||||
if (esz * cols == step)
|
||||
flags |= Mat::CONTINUOUS_FLAG;
|
||||
|
||||
datastart = data.get();
|
||||
dataend = data.get() + step * (rows - 1) + cols * esz;
|
||||
}
|
||||
}
|
||||
|
||||
void AscendMat::upload(InputArray arr) { upload(arr, AscendStream::Null()); }
|
||||
|
||||
void AscendMat::upload(InputArray arr, AscendStream& stream)
|
||||
{
|
||||
Mat mat = arr.getMat();
|
||||
CV_DbgAssert(!mat.empty());
|
||||
create(mat.rows, mat.cols, mat.type());
|
||||
aclrtMemcpy2dWarpper(data, 0, step, mat.data, mat.step[0], cols * elemSize(), rows, stream);
|
||||
}
|
||||
|
||||
void AscendMat::download(OutputArray dst) const { download(dst, AscendStream::Null()); }
|
||||
|
||||
void AscendMat::download(OutputArray _dst, AscendStream& stream) const
|
||||
{
|
||||
CV_DbgAssert(!empty());
|
||||
|
||||
_dst.create(size(), type());
|
||||
Mat dst = _dst.getMat();
|
||||
aclrtMemcpy2dWarpper(dst.data, dst.step[0], data, 0, step, cols * elemSize(), rows, stream);
|
||||
}
|
||||
|
||||
AscendMat::AscendMat(int rows_, int cols_, int type_, Scalar& s_, AscendMat::Allocator* allocator_)
|
||||
: flags(0), rows(rows_), cols(cols_), step(0), datastart(0), dataend(0), allocator(allocator_)
|
||||
{
|
||||
create(rows_, cols_, type_);
|
||||
setTo(s_);
|
||||
}
|
||||
|
||||
AscendMat::AscendMat(Size size_, int type_, Scalar& s_, AscendMat::Allocator* allocator_)
|
||||
: flags(0), rows(size_.height), cols(size_.width), step(0), datastart(0), dataend(0),
|
||||
allocator(allocator_)
|
||||
{
|
||||
create(size_.height, size_.width, type_);
|
||||
setTo(s_);
|
||||
}
|
||||
|
||||
AscendMat::AscendMat(InputArray _m, const Rect& roi) : AscendMat(_m, roi, AscendStream::Null()) {}
|
||||
|
||||
AscendMat::AscendMat(InputArray _m, const Rect& roi, AscendStream& stream)
|
||||
: rows(roi.height), cols(roi.width), allocator(defaultAllocator())
|
||||
{
|
||||
AscendMat m;
|
||||
m.upload(_m, stream);
|
||||
step = m.step;
|
||||
data = m.data;
|
||||
flags = m.flags;
|
||||
CV_Assert(0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y &&
|
||||
0 <= roi.height && roi.y + roi.height <= m.rows);
|
||||
size_t esz = CV_ELEM_SIZE(flags);
|
||||
size_t sizeMem = esz * roi.width * roi.height * m.channels();
|
||||
size_t offset = roi.y * m.step + roi.x * esz;
|
||||
|
||||
void* dst = malloc(sizeMem);
|
||||
size_t dpitch = roi.width * esz;
|
||||
std::shared_ptr<uchar> dstDevice = allocator->allocate(sizeMem);
|
||||
aclrtMemcpy2dWarpper(dst, dpitch, data, offset, step, dpitch, roi.height, stream);
|
||||
aclrtMemcpy2dWarpper(dstDevice, 0, dpitch, dst, dpitch, dpitch, roi.height, stream);
|
||||
data = dstDevice;
|
||||
step = dpitch;
|
||||
free(dst);
|
||||
updateContinuityFlag();
|
||||
}
|
||||
|
||||
AscendMat& AscendMat::setTo(const Scalar& sc) { return setTo(sc, AscendStream::Null()); }
|
||||
|
||||
AscendMat& AscendMat::setTo(const Scalar& sc, AscendStream& stream)
|
||||
{
|
||||
size_t totalBytes = (size_t)rows * cols * elemSize();
|
||||
if (totalBytes == 0)
|
||||
return *this;
|
||||
|
||||
aclrtMemsetWarpper(data, 0, totalBytes, stream);
|
||||
AscendMat dst(rows, cols, type());
|
||||
arithm_op(*this, sc, dst, "Add", stream);
|
||||
swap(dst);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
AscendMat& AscendMat::setTo(float sc) { return setTo(sc, AscendStream::Null()); }
|
||||
|
||||
AscendMat& AscendMat::setTo(float sc, AscendStream& stream)
|
||||
{
|
||||
size_t totalBytes = (size_t)rows * cols * elemSize();
|
||||
if (totalBytes == 0)
|
||||
return *this;
|
||||
|
||||
aclrtMemsetWarpper(data, 0, totalBytes, stream);
|
||||
|
||||
AscendMat dst(rows, cols, type());
|
||||
arithm_op(*this, sc, dst, "Adds", stream);
|
||||
swap(dst);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void AscendMat::convertTo(AscendMat& dst, int rtype) const
|
||||
{
|
||||
convertTo(dst, rtype, AscendStream::Null());
|
||||
}
|
||||
|
||||
void AscendMat::convertTo(AscendMat& dst, int _rtype, AscendStream& stream) const
|
||||
{
|
||||
int cn = channels();
|
||||
dst.create(rows, cols, CV_MAKE_TYPE(_rtype, cn));
|
||||
convertTo(dst, stream);
|
||||
}
|
||||
|
||||
void AscendMat::convertTo(AscendMat& dst, AscendStream& stream) const
|
||||
{
|
||||
OperatorRunner runner;
|
||||
runner.setOp("Cast")
|
||||
.addInput(*this, "x")
|
||||
.addOutput(dst, "y")
|
||||
.addAttr((int32_t)(getACLType(dst.depth())), "dst_type")
|
||||
.run(stream);
|
||||
}
|
||||
} // namespace cann
|
||||
} // namespace cv
|
||||
@@ -0,0 +1,516 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include <acl/acl.h>
|
||||
#include <acl/acl_op_compiler.h>
|
||||
#include "precomp.hpp"
|
||||
#include "opencv2/core/private.hpp"
|
||||
namespace cv
|
||||
{
|
||||
namespace cann
|
||||
{
|
||||
/*******************************Acl Error Checker*****************************/
|
||||
void checkAclError(aclError err, const char* file, const int line, const char* func)
|
||||
{
|
||||
if (ACL_SUCCESS != err)
|
||||
{
|
||||
const char* errMsg = aclGetRecentErrMsg();
|
||||
cv::error(cv::Error::StsError, errMsg == nullptr ? "" : errMsg, func, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
void checkAclPtr(void* ptr, const char* file, const int line, const char* func)
|
||||
{
|
||||
if (nullptr == ptr)
|
||||
{
|
||||
const char* errMsg = aclGetRecentErrMsg();
|
||||
cv::error(cv::Error::StsError, errMsg == nullptr ? "" : errMsg, func, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************Acl Runtime Warpper****************************/
|
||||
void aclrtMallocWarpper(void** data, size_t size)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtMalloc(data, size, ACL_MEM_MALLOC_HUGE_FIRST));
|
||||
}
|
||||
|
||||
void aclrtFreeWarpper(void* data) { CV_ACL_SAFE_CALL(aclrtFree(data)); }
|
||||
|
||||
void aclrtMemcpyWarpper(std::shared_ptr<uchar>& dst, size_t offset, const void* src, size_t size,
|
||||
AscendStream& stream)
|
||||
{
|
||||
aclrtStream rawStream = AscendStreamAccessor::getStream(stream);
|
||||
if (rawStream == nullptr)
|
||||
CV_ACL_SAFE_CALL(
|
||||
aclrtMemcpy(dst.get() + offset, size, src, size, ACL_MEMCPY_HOST_TO_DEVICE));
|
||||
else
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtMemcpyAsync(dst.get() + offset, size, src, size,
|
||||
ACL_MEMCPY_HOST_TO_DEVICE, rawStream));
|
||||
if (offset == 0)
|
||||
stream.addTensorHolder(dst);
|
||||
}
|
||||
}
|
||||
|
||||
void aclrtMemcpyWarpper(void* dst, const std::shared_ptr<uchar>& src, size_t offset, size_t size,
|
||||
AscendStream& stream)
|
||||
{
|
||||
aclrtStream rawStream = AscendStreamAccessor::getStream(stream);
|
||||
if (rawStream == nullptr)
|
||||
CV_ACL_SAFE_CALL(
|
||||
aclrtMemcpy(dst, size, src.get() + offset, size, ACL_MEMCPY_DEVICE_TO_HOST));
|
||||
else
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtMemcpyAsync(dst, size, src.get() + offset, size,
|
||||
ACL_MEMCPY_DEVICE_TO_HOST, rawStream));
|
||||
if (offset == 0)
|
||||
stream.addTensorHolder(src);
|
||||
}
|
||||
}
|
||||
|
||||
void aclrtMemcpyWarpper(std::shared_ptr<uchar>& dst, size_t dstOffset,
|
||||
const std::shared_ptr<uchar>& src, size_t srcOffset, size_t size,
|
||||
AscendStream& stream)
|
||||
{
|
||||
aclrtStream rawStream = AscendStreamAccessor::getStream(stream);
|
||||
if (rawStream == nullptr)
|
||||
CV_ACL_SAFE_CALL(aclrtMemcpy(dst.get() + dstOffset, size, src.get() + srcOffset, size,
|
||||
ACL_MEMCPY_DEVICE_TO_DEVICE));
|
||||
else
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtMemcpyAsync(dst.get() + dstOffset, size, src.get() + srcOffset, size,
|
||||
ACL_MEMCPY_DEVICE_TO_DEVICE, rawStream));
|
||||
if (srcOffset == 0)
|
||||
stream.addTensorHolder(src);
|
||||
if (dstOffset == 0)
|
||||
stream.addTensorHolder(dst);
|
||||
}
|
||||
}
|
||||
|
||||
void aclrtMemcpy2dWarpper(std::shared_ptr<uchar>& dst, size_t offset, size_t dpitch,
|
||||
const void* src, size_t spitch, size_t width, size_t length,
|
||||
AscendStream& stream)
|
||||
{
|
||||
aclrtStream rawStream = AscendStreamAccessor::getStream(stream);
|
||||
if (rawStream == nullptr)
|
||||
CV_ACL_SAFE_CALL(aclrtMemcpy2d(dst.get() + offset, dpitch, src, spitch, width, length,
|
||||
ACL_MEMCPY_HOST_TO_DEVICE));
|
||||
else
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtMemcpy2dAsync(dst.get() + offset, dpitch, src, spitch, width, length,
|
||||
ACL_MEMCPY_HOST_TO_DEVICE, rawStream));
|
||||
stream.addTensorHolder(dst);
|
||||
}
|
||||
}
|
||||
|
||||
void aclrtMemcpy2dWarpper(void* dst, size_t dpitch, const std::shared_ptr<uchar>& src,
|
||||
size_t offset, size_t spitch, size_t width, size_t length,
|
||||
AscendStream& stream)
|
||||
{
|
||||
aclrtStream rawStream = AscendStreamAccessor::getStream(stream);
|
||||
if (rawStream == nullptr)
|
||||
CV_ACL_SAFE_CALL(aclrtMemcpy2d(dst, dpitch, src.get() + offset, spitch, width, length,
|
||||
ACL_MEMCPY_DEVICE_TO_HOST));
|
||||
else
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtMemcpy2dAsync(dst, dpitch, src.get() + offset, spitch, width, length,
|
||||
ACL_MEMCPY_DEVICE_TO_HOST, rawStream));
|
||||
stream.addTensorHolder(src);
|
||||
}
|
||||
}
|
||||
|
||||
void aclrtMemsetWarpper(std::shared_ptr<uchar>& ptr, int32_t value, size_t count,
|
||||
AscendStream& stream)
|
||||
{
|
||||
aclrtStream rawStream = AscendStreamAccessor::getStream(stream);
|
||||
if (rawStream == nullptr)
|
||||
CV_ACL_SAFE_CALL(aclrtMemset(ptr.get(), count, value, count));
|
||||
else
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtMemsetAsync(ptr.get(), count, value, count, rawStream));
|
||||
stream.addTensorHolder(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
aclDataType getACLType(int opencvdepth)
|
||||
{
|
||||
switch (opencvdepth)
|
||||
{
|
||||
case CV_8S:
|
||||
return ACL_INT8;
|
||||
case CV_16S:
|
||||
return ACL_INT16;
|
||||
case CV_8U:
|
||||
return ACL_UINT8;
|
||||
case CV_16U:
|
||||
return ACL_UINT16;
|
||||
case CV_32S:
|
||||
return ACL_INT32;
|
||||
case CV_32F:
|
||||
return ACL_FLOAT;
|
||||
case CV_64F:
|
||||
return ACL_DOUBLE;
|
||||
case CV_16F:
|
||||
return ACL_FLOAT16;
|
||||
default:
|
||||
return ACL_DT_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<uchar> mallocAndUpload(const void* data, size_t size, AscendStream& stream,
|
||||
AscendMat::Allocator* allocator)
|
||||
{
|
||||
std::shared_ptr<uchar> ptr = allocator->allocate(size);
|
||||
aclrtStream rawStream = AscendStreamAccessor::getStream(stream);
|
||||
|
||||
if (rawStream == nullptr)
|
||||
CV_ACL_SAFE_CALL(aclrtMemcpy(ptr.get(), size, data, size, ACL_MEMCPY_HOST_TO_DEVICE));
|
||||
else
|
||||
CV_ACL_SAFE_CALL(
|
||||
aclrtMemcpyAsync(ptr.get(), size, data, size, ACL_MEMCPY_HOST_TO_DEVICE, rawStream));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**************************Acl attribute preparation**************************/
|
||||
|
||||
OperatorRunner& OperatorRunner::reset()
|
||||
{
|
||||
holder.clear();
|
||||
op.clear();
|
||||
for (auto desc : inputDesc_)
|
||||
{
|
||||
aclDestroyTensorDesc(desc);
|
||||
}
|
||||
for (auto desc : outputDesc_)
|
||||
{
|
||||
aclDestroyTensorDesc(desc);
|
||||
}
|
||||
for (auto buf : inputBuffers_)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclDestroyDataBuffer(buf));
|
||||
}
|
||||
for (auto buf : outputBuffers_)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclDestroyDataBuffer(buf));
|
||||
}
|
||||
if (opAttrInit)
|
||||
aclopDestroyAttr(opAttr_);
|
||||
inputDesc_.clear();
|
||||
outputDesc_.clear();
|
||||
inputBuffers_.clear();
|
||||
outputBuffers_.clear();
|
||||
opAttrInit = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::setOp(const char* opName)
|
||||
{
|
||||
reset();
|
||||
opAttr_ = CV_ACL_SAFE_CALL_PTR(aclopCreateAttr());
|
||||
opAttrInit = true;
|
||||
op = std::string(opName);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::addAttr(float value, const char* name)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclopSetAttrFloat(opAttr_, name, value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::addAttr(const char* value, const char* name)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclopSetAttrString(opAttr_, name, value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::addAttr(int value, const char* name)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclopSetAttrInt(opAttr_, name, value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::addAttr(bool value, const char* name)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclopSetAttrBool(opAttr_, name, value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::addAttr(const int64_t* value, int size, const char* name)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclopSetAttrListInt(opAttr_, name, size, value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::addInput(AscendTensor& tensor)
|
||||
{
|
||||
auto descPtr = CV_ACL_SAFE_CALL_PTR(
|
||||
aclCreateTensorDesc(tensor.dtype, tensor.dims.size(), &tensor.dims[0], tensor.format));
|
||||
if (descPtr != nullptr)
|
||||
{
|
||||
if (tensor.name != nullptr && strlen(tensor.name) != 0)
|
||||
aclSetTensorDescName(descPtr, tensor.name);
|
||||
inputDesc_.push_back(descPtr);
|
||||
}
|
||||
auto bufPtr = CV_ACL_SAFE_CALL_PTR(aclCreateDataBuffer(tensor.data.get(), tensor.dataSize));
|
||||
if (bufPtr != nullptr)
|
||||
inputBuffers_.push_back(bufPtr);
|
||||
holder.insert(tensor.data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::addOutput(AscendTensor& tensor)
|
||||
{
|
||||
auto descPtr = CV_ACL_SAFE_CALL_PTR(
|
||||
aclCreateTensorDesc(tensor.dtype, tensor.dims.size(), &tensor.dims[0], tensor.format));
|
||||
if (descPtr != nullptr)
|
||||
{
|
||||
if (tensor.name != nullptr && strlen(tensor.name) != 0)
|
||||
aclSetTensorDescName(descPtr, tensor.name);
|
||||
outputDesc_.push_back(descPtr);
|
||||
}
|
||||
auto bufPtr = CV_ACL_SAFE_CALL_PTR(aclCreateDataBuffer(tensor.data.get(), tensor.dataSize));
|
||||
if (bufPtr != nullptr)
|
||||
outputBuffers_.push_back(bufPtr);
|
||||
holder.insert(tensor.data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::addInput(const AscendMat& mat, const char* name)
|
||||
{
|
||||
AscendTensor tensor(mat, name);
|
||||
return addInput(tensor);
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::addOutput(AscendMat& mat, const char* name)
|
||||
{
|
||||
AscendTensor tensor(mat, name);
|
||||
return addOutput(tensor);
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::addInput(const Scalar& sc, int type, const char* name)
|
||||
{
|
||||
uchar rawData[32];
|
||||
cv::scalarToRawData(sc, rawData, type, 0);
|
||||
std::shared_ptr<uchar> scPtr = mallocAndUpload(
|
||||
rawData, (CV_ELEM_SIZE(type)), AscendStream::Null(), AscendMat::defaultAllocator());
|
||||
|
||||
int64_t dims[] = {1, 1, 1, (CV_MAT_CN(type))};
|
||||
AscendTensor tensor(scPtr, (CV_ELEM_SIZE(type)), dims, sizeof(dims) / sizeof(dims[0]),
|
||||
getACLType(CV_MAT_DEPTH(type)), name);
|
||||
return addInput(tensor);
|
||||
}
|
||||
|
||||
OperatorRunner& OperatorRunner::run(AscendStream& stream)
|
||||
{
|
||||
aclrtStream rawStream = AscendStreamAccessor::getStream(stream);
|
||||
CV_ACL_SAFE_CALL(aclopCompileAndExecute(op.c_str(), inputDesc_.size(), inputDesc_.data(),
|
||||
inputBuffers_.data(), outputDesc_.size(),
|
||||
outputDesc_.data(), outputBuffers_.data(), opAttr_,
|
||||
ACL_ENGINE_SYS, ACL_COMPILE_SYS, NULL, rawStream));
|
||||
if (rawStream == nullptr)
|
||||
CV_ACL_SAFE_CALL(aclrtSynchronizeStream(rawStream));
|
||||
else
|
||||
{
|
||||
for (const auto& ptr : holder)
|
||||
stream.addTensorHolder(ptr);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/********************************Ascend Tensor********************************/
|
||||
|
||||
AscendTensor::AscendTensor(std::shared_ptr<uchar> _data, size_t _dataSize, int64_t* _dims,
|
||||
size_t _dimSize, aclDataType _dtype, const char* _name,
|
||||
aclFormat _format)
|
||||
: name(_name), data(_data), dataSize(_dataSize), dtype(_dtype), format(_format)
|
||||
{
|
||||
dims.assign(_dims, _dims + _dimSize);
|
||||
}
|
||||
|
||||
AscendTensor::AscendTensor(const AscendMat& ascendMat, const char* _name, aclFormat _format)
|
||||
: name(_name), format(_format)
|
||||
{
|
||||
data = ascendMat.data;
|
||||
// Ascend can't process with gaps in matrix.
|
||||
CV_Assert(ascendMat.isContinuous());
|
||||
dataSize = ascendMat.rows * ascendMat.cols * ascendMat.elemSize();
|
||||
|
||||
switch (_format)
|
||||
{
|
||||
case ACL_FORMAT_NHWC:
|
||||
case ACL_FORMAT_ND:
|
||||
dims.resize(4);
|
||||
// Batch, default = 1.
|
||||
dims[0] = 1;
|
||||
// Default OpenCV image format = NHWC.
|
||||
dims[1] = ascendMat.rows;
|
||||
dims[2] = ascendMat.cols;
|
||||
dims[3] = ascendMat.channels();
|
||||
break;
|
||||
case ACL_FORMAT_NCHW:
|
||||
dims.resize(4);
|
||||
dims[0] = 1;
|
||||
dims[1] = ascendMat.channels();
|
||||
dims[2] = ascendMat.rows;
|
||||
dims[3] = ascendMat.cols;
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsBadArg, "Unknown/unsupported matrix format");
|
||||
}
|
||||
|
||||
dtype = getACLType(ascendMat.depth());
|
||||
}
|
||||
|
||||
/**********************************Device*************************************/
|
||||
void setDevice(int device_id)
|
||||
{
|
||||
aclrtContext context;
|
||||
CV_ACL_SAFE_CALL(aclrtSetDevice(device_id));
|
||||
CV_ACL_SAFE_CALL(aclrtCreateContext(&context, device_id));
|
||||
}
|
||||
|
||||
void resetDevice() { CV_ACL_SAFE_CALL(aclrtResetDevice(getDevice())); }
|
||||
|
||||
int32_t getDevice()
|
||||
{
|
||||
int32_t deviceId;
|
||||
CV_ACL_SAFE_CALL(aclrtGetDevice(&deviceId));
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
void initAcl() { CV_ACL_SAFE_CALL(aclInit(nullptr)); }
|
||||
|
||||
void finalizeAcl() { CV_ACL_SAFE_CALL(aclFinalize()); }
|
||||
|
||||
class DefaultDeviceInitializer
|
||||
{
|
||||
public:
|
||||
DefaultDeviceInitializer();
|
||||
~DefaultDeviceInitializer();
|
||||
|
||||
AscendStream& getNullAscendStream(int deviceId);
|
||||
|
||||
private:
|
||||
std::vector<Ptr<AscendStream>> streams_;
|
||||
Mutex streams_mtx_;
|
||||
};
|
||||
|
||||
DefaultDeviceInitializer::DefaultDeviceInitializer() {}
|
||||
|
||||
DefaultDeviceInitializer::~DefaultDeviceInitializer() { streams_.clear(); }
|
||||
|
||||
AscendStream& DefaultDeviceInitializer::getNullAscendStream(int deviceId)
|
||||
{
|
||||
AutoLock lock(streams_mtx_);
|
||||
|
||||
if (streams_.empty())
|
||||
{
|
||||
uint32_t deviceCount;
|
||||
CV_ACL_SAFE_CALL(aclrtGetDeviceCount(&deviceCount));
|
||||
|
||||
if (deviceCount > 0)
|
||||
streams_.resize(deviceCount);
|
||||
}
|
||||
|
||||
CV_DbgAssert(deviceId >= 0 && deviceId < static_cast<int>(streams_.size()));
|
||||
|
||||
if (streams_[deviceId].empty())
|
||||
{
|
||||
aclrtStream stream = nullptr;
|
||||
Ptr<AscendStream::Impl> impl = makePtr<AscendStream::Impl>(stream);
|
||||
streams_[deviceId] = Ptr<AscendStream>(new AscendStream(impl));
|
||||
}
|
||||
|
||||
return *streams_[deviceId];
|
||||
}
|
||||
|
||||
DefaultDeviceInitializer initializer;
|
||||
|
||||
/***********************************Event*************************************/
|
||||
AscendEvent::Impl::Impl() : event(nullptr), ownEvent(true)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtCreateEvent(&event));
|
||||
}
|
||||
|
||||
AscendEvent::Impl::Impl(aclrtEvent e) : event(e), ownEvent(false) {}
|
||||
|
||||
AscendEvent::Impl::~Impl()
|
||||
{
|
||||
if (event && ownEvent)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtDestroyEvent(event));
|
||||
}
|
||||
}
|
||||
|
||||
aclrtEvent AscendEventAccessor::getEvent(const AscendEvent& event) { return event.impl_->event; }
|
||||
|
||||
AscendEvent AscendEventAccessor::wrapEvent(aclrtEvent event)
|
||||
{
|
||||
return AscendEvent(makePtr<AscendEvent::Impl>(event));
|
||||
}
|
||||
|
||||
AscendEvent::AscendEvent() { impl_ = makePtr<Impl>(); }
|
||||
|
||||
void AscendEvent::record(AscendStream& stream)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtRecordEvent(impl_->event, AscendStreamAccessor::getStream(stream)));
|
||||
}
|
||||
|
||||
void AscendEvent::waitForComplete() const { CV_ACL_SAFE_CALL(aclrtSynchronizeEvent(impl_->event)); }
|
||||
|
||||
/************************************Stream***********************************/
|
||||
void AscendStream::Impl::AddTensorHolder(const std::shared_ptr<uchar>& tensorData)
|
||||
{
|
||||
tensorHolders.insert(tensorData);
|
||||
}
|
||||
|
||||
AscendStream::Impl::Impl() : stream(nullptr), ownStream(true)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtCreateStream(&stream));
|
||||
}
|
||||
|
||||
AscendStream::Impl::Impl(aclrtStream s) : stream(s), ownStream(false) {}
|
||||
|
||||
aclrtStream AscendStreamAccessor::getStream(const AscendStream& stream)
|
||||
{
|
||||
return stream.impl_->stream;
|
||||
}
|
||||
|
||||
AscendStream AscendStreamAccessor::wrapStream(aclrtStream stream)
|
||||
{
|
||||
return AscendStream(makePtr<AscendStream::Impl>(stream));
|
||||
}
|
||||
|
||||
AscendStream wrapStream(size_t AscendStreamAddress)
|
||||
{
|
||||
return AscendStreamAccessor::wrapStream(reinterpret_cast<aclrtStream>(AscendStreamAddress));
|
||||
}
|
||||
|
||||
AscendStream::AscendStream() { impl_ = makePtr<Impl>(); }
|
||||
|
||||
void AscendStream::waitForCompletion()
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtSynchronizeStream(impl_->stream));
|
||||
impl_->tensorHolders.clear();
|
||||
}
|
||||
|
||||
void AscendStream::waitAscendEvent(const AscendEvent& event)
|
||||
{
|
||||
CV_ACL_SAFE_CALL(aclrtStreamWaitEvent(impl_->stream, AscendEventAccessor::getEvent(event)));
|
||||
}
|
||||
|
||||
AscendStream& AscendStream::Null()
|
||||
{
|
||||
const uint32_t deviceId = getDevice();
|
||||
return initializer.getNullAscendStream(deviceId);
|
||||
}
|
||||
|
||||
void AscendStream::addTensorHolder(const std::shared_ptr<uchar>& holder)
|
||||
{
|
||||
impl_->AddTensorHolder(holder);
|
||||
}
|
||||
|
||||
} // namespace cann
|
||||
} // namespace cv
|
||||
@@ -0,0 +1,777 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace cann
|
||||
{
|
||||
// Integer type images will have a loss of accuracy during calculation, so they must be converted to
|
||||
// float before calculation.
|
||||
static AscendMat convertTo(const AscendMat& src, int dtype, AscendStream& stream)
|
||||
{
|
||||
AscendMat ret;
|
||||
if (src.depth() != dtype)
|
||||
src.convertTo(ret, dtype, stream);
|
||||
else
|
||||
ret = src;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void convertBack(const AscendMat& src, AscendMat& dst, AscendStream& stream)
|
||||
{
|
||||
if (src.depth() != dst.depth())
|
||||
src.convertTo(dst, stream);
|
||||
}
|
||||
|
||||
//! Set alpha channel to a Mat.
|
||||
static void matAlphaSet(AscendMat& mat, int dtype, AscendStream& stream)
|
||||
{
|
||||
if (dtype < 0)
|
||||
dtype = mat.depth();
|
||||
|
||||
if (mat.depth() == CV_8U || mat.depth() == CV_16U)
|
||||
{
|
||||
size_t size = mat.rows * mat.step;
|
||||
aclrtMemsetWarpper(mat.data, 255, size, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dtype == CV_32F)
|
||||
mat.setTo(1.0f, stream);
|
||||
else
|
||||
mat.setTo((dtype == CV_8U ? (1 << 8) : (1 << 16)) - 1, stream);
|
||||
}
|
||||
}
|
||||
|
||||
inline void checkImg(const AscendMat& mat)
|
||||
{
|
||||
int depth = mat.depth();
|
||||
CV_Assert(!mat.empty());
|
||||
CV_Assert(depth == CV_8U || depth == CV_16U || depth == CV_32F);
|
||||
}
|
||||
|
||||
inline void cvtBGRtoBGR(const AscendMat& src, AscendMat& dst, int dcn, bool swapBlue,
|
||||
AscendStream& stream)
|
||||
{
|
||||
checkImg(src);
|
||||
CV_Assert(src.channels() == 3 || src.channels() == 4);
|
||||
|
||||
AscendMat matChannels[4];
|
||||
split(src, matChannels, stream);
|
||||
|
||||
if (swapBlue)
|
||||
std::swap(matChannels[0], matChannels[2]);
|
||||
|
||||
if (dcn == 4 && src.channels() != 4)
|
||||
{
|
||||
AscendMat& alpha = matChannels[3];
|
||||
alpha.create(src.rows, src.cols, CV_MAKE_TYPE(src.depth(), 1));
|
||||
matAlphaSet(alpha, -1, stream);
|
||||
}
|
||||
|
||||
merge(matChannels, dcn, dst, stream);
|
||||
}
|
||||
|
||||
inline void cvtBGRtoBGR(InputArray& _src, OutputArray& _dst, int dcn, bool swapBlue,
|
||||
AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
cvtBGRtoBGR(src, dst, dcn, swapBlue, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
// TODO duplicated code
|
||||
static const float B2YF = 0.114f;
|
||||
static const float G2YF = 0.587f;
|
||||
static const float R2YF = 0.299f;
|
||||
|
||||
inline void cvtBGRtoGray(const AscendMat& src, AscendMat& dst, int, bool swapBlue,
|
||||
AscendStream& stream)
|
||||
{
|
||||
checkImg(src);
|
||||
CV_Assert(src.channels() == 3 || src.channels() == 4);
|
||||
|
||||
float coeffs[] = {B2YF, G2YF, R2YF};
|
||||
dst.create(src.rows, src.cols, CV_MAKE_TYPE(src.depth(), 1));
|
||||
AscendMat formatedSrc = convertTo(src, CV_32F, stream);
|
||||
AscendMat formatedDst = convertTo(dst, CV_32F, stream);
|
||||
|
||||
// For RGB
|
||||
if (swapBlue)
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
|
||||
Scalar sc = {coeffs[0], coeffs[1], coeffs[2], 0};
|
||||
AscendMat grayRet(formatedSrc.rows, formatedSrc.cols, formatedSrc.type());
|
||||
arithm_op(formatedSrc, sc, grayRet, "Mul", stream);
|
||||
|
||||
AscendMat matChannels[4];
|
||||
split(grayRet, matChannels, stream);
|
||||
|
||||
OperatorRunner runner;
|
||||
runner.setOp("AddN")
|
||||
.addInput(matChannels[0], "x0")
|
||||
.addInput(matChannels[1], "x1")
|
||||
.addInput(matChannels[2], "x2")
|
||||
.addOutput(formatedDst, "y")
|
||||
.addAttr(3, "N")
|
||||
.run(stream);
|
||||
|
||||
convertBack(formatedDst, dst, stream);
|
||||
}
|
||||
|
||||
inline void cvtBGRtoGray(const InputArray& _src, OutputArray& _dst, int, bool swapBlue,
|
||||
AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
cvtBGRtoGray(src, dst, 0, swapBlue, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
inline void cvtGraytoBGR(const AscendMat& src, AscendMat& dst, int dcn, bool, AscendStream& stream)
|
||||
{
|
||||
checkImg(src);
|
||||
CV_Assert(src.channels() == 1);
|
||||
|
||||
AscendMat matChannels[4];
|
||||
for (int i = 0; i < 3; i++)
|
||||
matChannels[i] = src;
|
||||
|
||||
if (dcn == 4)
|
||||
{
|
||||
AscendMat& alpha = matChannels[3];
|
||||
alpha.create(src.rows, src.cols, CV_MAKE_TYPE(src.depth(), 1));
|
||||
matAlphaSet(alpha, -1, stream);
|
||||
}
|
||||
|
||||
merge(matChannels, dcn, dst, stream);
|
||||
}
|
||||
|
||||
inline void cvtGraytoBGR(const InputArray& _src, OutputArray& _dst, int dcn, bool,
|
||||
AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
cvtGraytoBGR(src, dst, dcn, false, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
static const float RGB2XYZ_D65[] = {0.412453, 0.357580, 0.180423, 0.212671, 0.715160,
|
||||
0.072169, 0.019334, 0.119193, 0.950227};
|
||||
|
||||
static const float XYZ2RGB_D65[] = {3.240479, -1.53715, -0.498535, -0.969256, 1.875991,
|
||||
0.041556, 0.055648, -0.204043, 1.057311};
|
||||
|
||||
inline void matMulRGB(const AscendMat& src, AscendMat& dst, float* matrix, AscendStream& stream)
|
||||
{
|
||||
checkImg(src);
|
||||
CV_Assert(src.channels() == 3);
|
||||
|
||||
dst.create(src.rows, src.cols, src.type());
|
||||
AscendMat formatedSrc = convertTo(src, CV_32F, stream);
|
||||
AscendMat formatedDst = convertTo(dst, CV_32F, stream);
|
||||
|
||||
int64_t dims[] = {3, 3};
|
||||
OperatorRunner runner;
|
||||
runner.setOp("BatchMatMulV2")
|
||||
.addInput(formatedSrc, "x1")
|
||||
.addInput<float>(matrix, dims, 2, getACLType(CV_32F), "x2")
|
||||
.addOutput(formatedDst, "y")
|
||||
.addAttr(false, "adj_x1")
|
||||
.addAttr(true, "adj_x2")
|
||||
.run(stream);
|
||||
|
||||
if (src.depth() != CV_32F)
|
||||
{
|
||||
AscendMat thresholdTempMat(formatedSrc.size(), formatedSrc.type());
|
||||
uint16_t thresh = (src.depth() == CV_8U ? (1 << 8) : (1 << 16)) - 1;
|
||||
threshold(formatedDst, thresholdTempMat, thresh, 0, 2 /*THRESH_TRUNC*/, stream);
|
||||
threshold(thresholdTempMat, formatedDst, 0, 0, 3 /*THRESH_TOZERO*/, stream);
|
||||
}
|
||||
|
||||
convertBack(formatedDst, dst, stream);
|
||||
}
|
||||
|
||||
// TODO: should deal with overflow. set 255 instead of cut off.
|
||||
inline void cvtBGRtoXYZ(const AscendMat& src, AscendMat& dst, int, bool swapBlue,
|
||||
AscendStream& stream)
|
||||
{
|
||||
float coeffs[9];
|
||||
memcpy(coeffs, RGB2XYZ_D65, 9 * sizeof(float));
|
||||
if (!swapBlue)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
std::swap(coeffs[3], coeffs[5]);
|
||||
std::swap(coeffs[6], coeffs[8]);
|
||||
}
|
||||
matMulRGB(src, dst, coeffs, stream);
|
||||
}
|
||||
|
||||
inline void cvtBGRtoXYZ(const InputArray& _src, OutputArray& _dst, int, bool swapBlue,
|
||||
AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
cvtBGRtoXYZ(src, dst, 0, swapBlue, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
inline void cvtXYZtoBGR(const AscendMat& src, AscendMat& dst, int dcn, bool swapBlue,
|
||||
AscendStream& stream)
|
||||
{
|
||||
float coeffs[9];
|
||||
memcpy(coeffs, XYZ2RGB_D65, 9 * sizeof(float));
|
||||
if (!swapBlue)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[6]);
|
||||
std::swap(coeffs[1], coeffs[7]);
|
||||
std::swap(coeffs[2], coeffs[8]);
|
||||
}
|
||||
|
||||
if (dcn == 4)
|
||||
{
|
||||
AscendMat tempMat[2];
|
||||
matMulRGB(src, tempMat[0], coeffs, stream);
|
||||
tempMat[1].create(tempMat[0].rows, tempMat[0].cols, CV_MAKE_TYPE(tempMat[0].depth(), 1));
|
||||
matAlphaSet(tempMat[1], -1, stream);
|
||||
merge(tempMat, 2, dst, stream);
|
||||
}
|
||||
else
|
||||
matMulRGB(src, dst, coeffs, stream);
|
||||
}
|
||||
|
||||
inline void cvtXYZtoBGR(const InputArray& _src, OutputArray& _dst, int dcn, bool swapBlue,
|
||||
AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
cvtXYZtoBGR(src, dst, dcn, swapBlue, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
// TODO duplicated code
|
||||
static const float YCRF = 0.713f;
|
||||
static const float YCBF = 0.564f;
|
||||
static const float R2VF = 0.877f;
|
||||
static const float B2UF = 0.492f;
|
||||
inline void cvtBGRtoYCrCb(const AscendMat& src, AscendMat& dst, float* coeffs, bool swapBlue,
|
||||
bool yuvOrder, AscendStream& stream)
|
||||
{
|
||||
checkImg(src);
|
||||
CV_Assert(src.channels() == 3);
|
||||
|
||||
int buleIdx = swapBlue ? 2 : 0;
|
||||
int depth = src.depth();
|
||||
float delta = (depth == CV_8U) ? 128 : ((depth == CV_16U) ? 32768 : 0.5);
|
||||
|
||||
dst.create(src.rows, src.cols, src.type());
|
||||
AscendMat formatedSrc = convertTo(src, CV_32F, stream);
|
||||
AscendMat formatedDst = convertTo(dst, CV_32F, stream);
|
||||
|
||||
AscendMat YCrCb[3], RGB[3];
|
||||
split(formatedSrc, RGB, stream);
|
||||
cvtBGRtoGray(formatedSrc, YCrCb[0], 1, swapBlue, stream);
|
||||
YCrCb[1].create(YCrCb[0].rows, YCrCb[0].cols, YCrCb[0].type());
|
||||
YCrCb[2].create(YCrCb[0].rows, YCrCb[0].cols, YCrCb[0].type());
|
||||
|
||||
AscendMat tempMat1(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1)),
|
||||
tempMat2(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1));
|
||||
|
||||
arithm_op(RGB[buleIdx ^ 2], YCrCb[0], tempMat1, "Sub", stream);
|
||||
arithm_op(tempMat1, coeffs[0], tempMat2, "Muls", stream);
|
||||
arithm_op(tempMat2, delta, YCrCb[1], "Adds", stream);
|
||||
|
||||
arithm_op(RGB[buleIdx], YCrCb[0], tempMat1, "Sub", stream);
|
||||
arithm_op(tempMat1, coeffs[1], tempMat2, "Muls", stream);
|
||||
arithm_op(tempMat2, delta, YCrCb[2], "Adds", stream);
|
||||
|
||||
if (yuvOrder)
|
||||
std::swap(YCrCb[1], YCrCb[2]);
|
||||
|
||||
merge(YCrCb, 3, formatedDst, stream);
|
||||
if (src.depth() != CV_32F)
|
||||
{
|
||||
AscendMat thresholdTempMat(formatedSrc.size(), formatedSrc.type());
|
||||
uint16_t thresh = (src.depth() == CV_8U ? (1 << 8) : (1 << 16)) - 1;
|
||||
threshold(formatedDst, thresholdTempMat, thresh, 0, 2 /*THRESH_TRUNC*/, stream);
|
||||
threshold(thresholdTempMat, formatedDst, 0, 0, 3 /*THRESH_TOZERO*/, stream);
|
||||
}
|
||||
|
||||
convertBack(formatedDst, dst, stream);
|
||||
}
|
||||
|
||||
inline void cvtBGRtoYCrCb(const InputArray& _src, OutputArray& _dst, float* coeffs, bool swapBlue,
|
||||
bool yuvOrder, AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
cvtBGRtoYCrCb(src, dst, coeffs, swapBlue, yuvOrder, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
static const float CR2RF = 1.403f;
|
||||
static const float CR2GF = -0.714f;
|
||||
static const float CB2GF = -0.344f;
|
||||
static const float CB2BF = 1.773f;
|
||||
|
||||
static const float V2RF = 1.140f;
|
||||
static const float V2GF = -0.581f;
|
||||
static const float U2GF = -0.395f;
|
||||
static const float U2BF = 2.032f;
|
||||
|
||||
inline void cvtYCrCbtoBGR(const AscendMat& src, AscendMat& dst, int dcn, float* coeffs,
|
||||
bool swapBlue, bool yuvOrder, AscendStream& stream)
|
||||
{
|
||||
checkImg(src);
|
||||
CV_Assert(src.channels() == 3);
|
||||
|
||||
int buleIdx = swapBlue ? 2 : 0;
|
||||
int depth = src.depth();
|
||||
float delta = (depth == CV_8U) ? 128 : ((depth == CV_16U) ? 32768 : 0.5);
|
||||
|
||||
dst.create(src.rows, src.cols, CV_MAKE_TYPE(src.depth(), dcn));
|
||||
AscendMat formatedSrc = convertTo(src, CV_32F, stream);
|
||||
AscendMat formatedDst = convertTo(dst, CV_32F, stream);
|
||||
|
||||
AscendMat YCrCb[3], RGB[4];
|
||||
split(formatedSrc, YCrCb, stream);
|
||||
if (yuvOrder)
|
||||
std::swap(YCrCb[1], YCrCb[2]);
|
||||
|
||||
RGB[0].create(formatedSrc.rows, formatedSrc.cols, CV_MAKE_TYPE(formatedSrc.depth(), 1));
|
||||
RGB[1].create(formatedSrc.rows, formatedSrc.cols, CV_MAKE_TYPE(formatedSrc.depth(), 1));
|
||||
RGB[2].create(formatedSrc.rows, formatedSrc.cols, CV_MAKE_TYPE(formatedSrc.depth(), 1));
|
||||
AscendMat tempMat1(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1)),
|
||||
tempMat2(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1)),
|
||||
CbSubDelta(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1)),
|
||||
CrSubDelta(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1));
|
||||
|
||||
arithm_op(YCrCb[1], (0.0f - delta), CrSubDelta, "Adds", stream);
|
||||
arithm_op(YCrCb[2], (0.0f - delta), CbSubDelta, "Adds", stream);
|
||||
arithm_op(CrSubDelta, coeffs[0], tempMat1, "Muls", stream);
|
||||
arithm_op(YCrCb[0], tempMat1, RGB[buleIdx ^ 2], "Add", stream);
|
||||
|
||||
arithm_op(CrSubDelta, coeffs[1], tempMat1, "Muls", stream);
|
||||
arithm_op(YCrCb[0], tempMat1, tempMat2, "Add", stream);
|
||||
arithm_op(CbSubDelta, coeffs[2], tempMat1, "Muls", stream);
|
||||
arithm_op(tempMat2, tempMat1, RGB[1], "Add", stream);
|
||||
|
||||
arithm_op(CbSubDelta, coeffs[3], tempMat1, "Muls", stream);
|
||||
arithm_op(YCrCb[0], tempMat1, RGB[buleIdx], "Add", stream);
|
||||
|
||||
if (dcn == 4)
|
||||
{
|
||||
RGB[3].create(RGB[0].rows, RGB[0].cols, RGB[0].type());
|
||||
matAlphaSet(RGB[3], src.depth(), stream);
|
||||
}
|
||||
|
||||
merge(RGB, dcn, formatedDst, stream);
|
||||
if (src.depth() != CV_32F)
|
||||
{
|
||||
AscendMat thresholdTempMat(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), dcn));
|
||||
uint16_t thresh = (src.depth() == CV_8U ? (1 << 8) : (1 << 16)) - 1;
|
||||
threshold(formatedDst, thresholdTempMat, thresh, 0, 2 /*THRESH_TRUNC*/, stream);
|
||||
threshold(thresholdTempMat, formatedDst, 0, 0, 3 /*THRESH_TOZERO*/, stream);
|
||||
}
|
||||
|
||||
convertBack(formatedDst, dst, stream);
|
||||
}
|
||||
|
||||
inline void cvtYCrCbtoBGR(const InputArray& _src, OutputArray& _dst, int dcn, float* coeffs,
|
||||
bool swapBlue, bool yuvOrder, AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
cvtYCrCbtoBGR(src, dst, dcn, coeffs, swapBlue, yuvOrder, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
// The input may be Input/OutputArray or AscendMat. Use templates to reduce duplicate code.
|
||||
template <typename SRC, typename DST>
|
||||
inline void BGR2BGRA(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoBGR(src, dst, 4, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void BGRA2BGR(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoBGR(src, dst, 3, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void BGR2RGBA(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoBGR(src, dst, 4, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void RGBA2BGR(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoBGR(src, dst, 3, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void BGR2RGB(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoBGR(src, dst, 3, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void BGRA2RGBA(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoBGR(src, dst, 4, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void BGR2GRAY(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoGray(src, dst, 1, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void RGB2GRAY(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoGray(src, dst, 1, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void GRAY2BGR(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtGraytoBGR(src, dst, 3, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void GRAY2BGRA(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtGraytoBGR(src, dst, 4, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void BGRA2GRAY(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoGray(src, dst, 1, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void RGBA2GRAY(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoGray(src, dst, 1, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void BGR2XYZ(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoXYZ(src, dst, 3, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void RGB2XYZ(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
cvtBGRtoXYZ(src, dst, 3, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void XYZ2BGR(const SRC& src, DST& dst, int dcn, AscendStream& stream)
|
||||
{
|
||||
if (dcn <= 0)
|
||||
dcn = 3;
|
||||
cvtXYZtoBGR(src, dst, dcn, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void XYZ2RGB(const SRC& src, DST& dst, int dcn, AscendStream& stream)
|
||||
{
|
||||
if (dcn <= 0)
|
||||
dcn = 3;
|
||||
cvtXYZtoBGR(src, dst, dcn, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void BGR2YCrCb(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
float coeffs[2];
|
||||
coeffs[0] = YCRF;
|
||||
coeffs[1] = YCBF;
|
||||
cvtBGRtoYCrCb(src, dst, coeffs, false, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void RGB2YCrCb(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
float coeffs[2];
|
||||
coeffs[0] = YCRF;
|
||||
coeffs[1] = YCBF;
|
||||
cvtBGRtoYCrCb(src, dst, coeffs, true, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void YCrCb2BGR(const SRC& src, DST& dst, int dcn, AscendStream& stream)
|
||||
{
|
||||
float coeffs[4];
|
||||
coeffs[0] = CR2RF;
|
||||
coeffs[1] = CR2GF;
|
||||
coeffs[2] = CB2GF;
|
||||
coeffs[3] = CB2BF;
|
||||
if (dcn <= 0)
|
||||
dcn = 3;
|
||||
cvtYCrCbtoBGR(src, dst, dcn, coeffs, false, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void YCrCb2RGB(const SRC& src, DST& dst, int dcn, AscendStream& stream)
|
||||
{
|
||||
float coeffs[4];
|
||||
coeffs[0] = CR2RF;
|
||||
coeffs[1] = CR2GF;
|
||||
coeffs[2] = CB2GF;
|
||||
coeffs[3] = CB2BF;
|
||||
if (dcn <= 0)
|
||||
dcn = 3;
|
||||
cvtYCrCbtoBGR(src, dst, dcn, coeffs, true, false, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void BGR2YUV(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
float coeffs[2];
|
||||
coeffs[0] = R2VF;
|
||||
coeffs[1] = B2UF;
|
||||
cvtBGRtoYCrCb(src, dst, coeffs, false, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void RGB2YUV(const SRC& src, DST& dst, int, AscendStream& stream)
|
||||
{
|
||||
float coeffs[2];
|
||||
coeffs[0] = R2VF;
|
||||
coeffs[1] = B2UF;
|
||||
cvtBGRtoYCrCb(src, dst, coeffs, true, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void YUV2BGR(const SRC& src, DST& dst, int dcn, AscendStream& stream)
|
||||
{
|
||||
float coeffs[4];
|
||||
coeffs[0] = V2RF;
|
||||
coeffs[1] = V2GF;
|
||||
coeffs[2] = U2GF;
|
||||
coeffs[3] = U2BF;
|
||||
if (dcn <= 0)
|
||||
dcn = 3;
|
||||
cvtYCrCbtoBGR(src, dst, dcn, coeffs, false, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
inline void YUV2RGB(const SRC& src, DST& dst, int dcn, AscendStream& stream)
|
||||
{
|
||||
float coeffs[4];
|
||||
coeffs[0] = V2RF;
|
||||
coeffs[1] = V2GF;
|
||||
coeffs[2] = U2GF;
|
||||
coeffs[3] = U2BF;
|
||||
if (dcn <= 0)
|
||||
dcn = 3;
|
||||
cvtYCrCbtoBGR(src, dst, dcn, coeffs, true, true, stream);
|
||||
}
|
||||
|
||||
template <typename SRC, typename DST>
|
||||
void cvtColorDo(const SRC& src, DST& dst, int code, int dcn, AscendStream& stream)
|
||||
{
|
||||
typedef void (*func_t)(const SRC& src, DST& dst, int dcn, AscendStream& stream);
|
||||
static const func_t funcs[] = {
|
||||
BGR2BGRA, // CV_BGR2BGRA =0
|
||||
BGRA2BGR, // CV_BGRA2BGR =1
|
||||
BGR2RGBA, // CV_BGR2RGBA =2
|
||||
RGBA2BGR, // CV_RGBA2BGR =3
|
||||
BGR2RGB, // CV_BGR2RGB =4
|
||||
BGRA2RGBA, // CV_BGRA2RGBA =5
|
||||
|
||||
BGR2GRAY, // CV_BGR2GRAY =6
|
||||
RGB2GRAY, // CV_RGB2GRAY =7
|
||||
GRAY2BGR, // CV_GRAY2BGR =8
|
||||
GRAY2BGRA, // CV_GRAY2BGRA =9
|
||||
BGRA2GRAY, // CV_BGRA2GRAY =10
|
||||
RGBA2GRAY, // CV_RGBA2GRAY =11
|
||||
|
||||
0, // CV_BGR2BGR565 =12
|
||||
0, // CV_RGB2BGR565 =13
|
||||
0, // CV_BGR5652BGR =14
|
||||
0, // CV_BGR5652RGB =15
|
||||
0, // CV_BGRA2BGR565 =16
|
||||
0, // CV_RGBA2BGR565 =17
|
||||
0, // CV_BGR5652BGRA =18
|
||||
0, // CV_BGR5652RGBA =19
|
||||
|
||||
0, // CV_GRAY2BGR565 =20
|
||||
0, // CV_BGR5652GRAY =21
|
||||
|
||||
0, // CV_BGR2BGR555 =22
|
||||
0, // CV_RGB2BGR555 =23
|
||||
0, // CV_BGR5552BGR =24
|
||||
0, // CV_BGR5552RGB =25
|
||||
0, // CV_BGRA2BGR555 =26
|
||||
0, // CV_RGBA2BGR555 =27
|
||||
0, // CV_BGR5552BGRA =28
|
||||
0, // CV_BGR5552RGBA =29
|
||||
|
||||
0, // CV_GRAY2BGR555 =30
|
||||
0, // CV_BGR5552GRAY =31
|
||||
|
||||
BGR2XYZ, // CV_BGR2XYZ =32
|
||||
RGB2XYZ, // CV_RGB2XYZ =33
|
||||
XYZ2BGR, // CV_XYZ2BGR =34
|
||||
XYZ2RGB, // CV_XYZ2RGB =35
|
||||
|
||||
BGR2YCrCb, // CV_BGR2YCrCb =36
|
||||
RGB2YCrCb, // CV_RGB2YCrCb =37
|
||||
YCrCb2BGR, // CV_YCrCb2BGR =38
|
||||
YCrCb2RGB, // CV_YCrCb2RGB =39
|
||||
|
||||
0, // CV_BGR2HSV =40
|
||||
0, // CV_RGB2HSV =41
|
||||
|
||||
0, // =42
|
||||
0, // =43
|
||||
|
||||
0, // CV_BGR2Lab =44
|
||||
0, // CV_RGB2Lab =45
|
||||
|
||||
0, // CV_BayerBG2BGR =46
|
||||
0, // CV_BayeRGB2BGR =47
|
||||
0, // CV_BayerRG2BGR =48
|
||||
0, // CV_BayerGR2BGR =49
|
||||
|
||||
0, // CV_BGR2Luv =50
|
||||
0, // CV_RGB2Luv =51
|
||||
|
||||
0, // CV_BGR2HLS =52
|
||||
0, // CV_RGB2HLS =53
|
||||
|
||||
0, // CV_HSV2BGR =54
|
||||
0, // CV_HSV2RGB =55
|
||||
|
||||
0, // CV_Lab2BGR =56
|
||||
0, // CV_Lab2RGB =57
|
||||
0, // CV_Luv2BGR =58
|
||||
0, // CV_Luv2RGB =59
|
||||
|
||||
0, // CV_HLS2BGR =60
|
||||
0, // CV_HLS2RGB =61
|
||||
|
||||
0, // CV_BayerBG2BGR_VNG =62
|
||||
0, // CV_BayeRGB2BGR_VNG =63
|
||||
0, // CV_BayerRG2BGR_VNG =64
|
||||
0, // CV_BayerGR2BGR_VNG =65
|
||||
|
||||
0, // CV_BGR2HSV_FULL = 66
|
||||
0, // CV_RGB2HSV_FULL = 67
|
||||
0, // CV_BGR2HLS_FULL = 68
|
||||
0, // CV_RGB2HLS_FULL = 69
|
||||
|
||||
0, // CV_HSV2BGR_FULL = 70
|
||||
0, // CV_HSV2RGB_FULL = 71
|
||||
0, // CV_HLS2BGR_FULL = 72
|
||||
0, // CV_HLS2RGB_FULL = 73
|
||||
|
||||
0, // CV_LBGR2Lab = 74
|
||||
0, // CV_LRGB2Lab = 75
|
||||
0, // CV_LBGR2Luv = 76
|
||||
0, // CV_LRGB2Luv = 77
|
||||
|
||||
0, // CV_Lab2LBGR = 78
|
||||
0, // CV_Lab2LRGB = 79
|
||||
0, // CV_Luv2LBGR = 80
|
||||
0, // CV_Luv2LRGB = 81
|
||||
|
||||
BGR2YUV, // CV_BGR2YUV = 82
|
||||
RGB2YUV, // CV_RGB2YUV = 83
|
||||
YUV2BGR, // CV_YUV2BGR = 84
|
||||
YUV2RGB, // CV_YUV2RGB = 85
|
||||
|
||||
0, // CV_BayerBG2GRAY = 86
|
||||
0, // CV_BayeRGB2GRAY = 87
|
||||
0, // CV_BayerRG2GRAY = 88
|
||||
0, // CV_BayerGR2GRAY = 89
|
||||
|
||||
// YUV 4:2:0 formats family
|
||||
0, // CV_YUV2RGB_NV12 = 90,
|
||||
0, // CV_YUV2BGR_NV12 = 91,
|
||||
0, // CV_YUV2RGB_NV21 = 92,
|
||||
0, // CV_YUV2BGR_NV21 = 93,
|
||||
|
||||
0, // CV_YUV2RGBA_NV12 = 94,
|
||||
0, // CV_YUV2BGRA_NV12 = 95,
|
||||
0, // CV_YUV2RGBA_NV21 = 96,
|
||||
0, // CV_YUV2BGRA_NV21 = 97,
|
||||
|
||||
0, // CV_YUV2RGB_YV12 = 98,
|
||||
0, // CV_YUV2BGR_YV12 = 99,
|
||||
0, // CV_YUV2RGB_IYUV = 100,
|
||||
0, // CV_YUV2BGR_IYUV = 101,
|
||||
|
||||
0, // CV_YUV2RGBA_YV12 = 102,
|
||||
0, // CV_YUV2BGRA_YV12 = 103,
|
||||
0, // CV_YUV2RGBA_IYUV = 104,
|
||||
0, // CV_YUV2BGRA_IYUV = 105,
|
||||
|
||||
0, // CV_YUV2GRAY_420 = 106,
|
||||
|
||||
// YUV 4:2:2 formats family
|
||||
0, // CV_YUV2RGB_UYVY = 107,
|
||||
0, // CV_YUV2BGR_UYVY = 108,
|
||||
0, // //CV_YUV2RGB_VYUY = 109,
|
||||
0, // //CV_YUV2BGR_VYUY = 110,
|
||||
|
||||
0, // CV_YUV2RGBA_UYVY = 111,
|
||||
0, // CV_YUV2BGRA_UYVY = 112,
|
||||
0, // //CV_YUV2RGBA_VYUY = 113,
|
||||
0, // //CV_YUV2BGRA_VYUY = 114,
|
||||
|
||||
0, // CV_YUV2RGB_YUY2 = 115,
|
||||
0, // CV_YUV2BGR_YUY2 = 116,
|
||||
0, // CV_YUV2RGB_YVYU = 117,
|
||||
0, // CV_YUV2BGR_YVYU = 118,
|
||||
|
||||
0, // CV_YUV2RGBA_YUY2 = 119,
|
||||
0, // CV_YUV2BGRA_YUY2 = 120,
|
||||
0, // CV_YUV2RGBA_YVYU = 121,
|
||||
0, // CV_YUV2BGRA_YVYU = 122,
|
||||
|
||||
0, // CV_YUV2GRAY_UYVY = 123,
|
||||
0, // CV_YUV2GRAY_YUY2 = 124,
|
||||
|
||||
// alpha premultiplication
|
||||
0, // CV_RGBA2mRGBA = 125,
|
||||
0, // CV_mRGBA2RGBA = 126,
|
||||
|
||||
0, // CV_COLORCVT_MAX = 127
|
||||
};
|
||||
|
||||
CV_Assert(code < 128);
|
||||
|
||||
func_t func = funcs[code];
|
||||
|
||||
if (func == 0)
|
||||
CV_Error(Error::StsBadFlag, "Unknown/unsupported color conversion code");
|
||||
|
||||
func(src, dst, dcn, stream);
|
||||
}
|
||||
|
||||
// Instantiate templates to avoid confusion in python code generation
|
||||
void cvtColor(const InputArray src, OutputArray dst, int code, int dcn, AscendStream& stream)
|
||||
{
|
||||
cvtColorDo(src, dst, code, dcn, stream);
|
||||
}
|
||||
|
||||
void cvtColor(const AscendMat& src, AscendMat& dst, int code, int dcn, AscendStream& stream)
|
||||
{
|
||||
cvtColorDo(src, dst, code, dcn, stream);
|
||||
}
|
||||
|
||||
} // namespace cann
|
||||
} // namespace cv
|
||||
@@ -0,0 +1,477 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace cann
|
||||
{
|
||||
// Transform data type from one to another. eg. from NCHW to NHWC.
|
||||
void transData(const AscendMat& src, AscendMat& dst, const char* from, const char* to,
|
||||
AscendStream& stream)
|
||||
{
|
||||
OperatorRunner runner;
|
||||
runner.setOp("TransData")
|
||||
.addInput(src, "src")
|
||||
.addOutput(dst, "dst")
|
||||
.addAttr(from, "src_format")
|
||||
.addAttr(to, "dst_format")
|
||||
.run(stream);
|
||||
}
|
||||
|
||||
void merge(const AscendMat* src, size_t n, AscendMat& dst, AscendStream& stream)
|
||||
{
|
||||
if (src == nullptr || n < 2)
|
||||
return;
|
||||
|
||||
int depth = src->depth();
|
||||
int rows = src->rows;
|
||||
int cols = src->cols;
|
||||
|
||||
// All matrix must have same size and type
|
||||
for (size_t i = 1; i < n; i++)
|
||||
{
|
||||
CV_Assert(src[i].depth() == depth && src[i].channels() == 1);
|
||||
CV_Assert(src[i].rows == rows && src[i].cols == cols);
|
||||
}
|
||||
|
||||
int cns = 0;
|
||||
for (size_t i = 0; i < n; i++)
|
||||
cns += src[i].channels();
|
||||
dst.create(src->rows, src->cols, CV_MAKE_TYPE(src->depth(), cns));
|
||||
|
||||
OperatorRunner runner;
|
||||
runner.setOp("ConcatD");
|
||||
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
runner.addInput(src[i], ("x" + std::to_string(i)).c_str());
|
||||
}
|
||||
|
||||
runner.addOutput(dst, "output_data").addAttr(3, "concat_dim").run(stream);
|
||||
}
|
||||
|
||||
void merge(const std::vector<AscendMat>& src, AscendMat& dst, AscendStream& stream)
|
||||
{
|
||||
merge(&src[0], src.size(), dst, stream);
|
||||
}
|
||||
|
||||
void merge(const AscendMat* src, size_t n, OutputArray& _dst, AscendStream& stream)
|
||||
{
|
||||
AscendMat dst;
|
||||
merge(src, n, dst, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
void merge(const std::vector<AscendMat>& src, OutputArray& dst, AscendStream& stream)
|
||||
{
|
||||
merge(&src[0], src.size(), dst, stream);
|
||||
}
|
||||
|
||||
void split(const AscendMat& src, AscendMat* dst, AscendStream& stream)
|
||||
{
|
||||
if (src.empty() || dst == nullptr)
|
||||
return;
|
||||
|
||||
int cn = src.channels();
|
||||
|
||||
OperatorRunner runner;
|
||||
runner.setOp("SplitD").addInput(src, "x");
|
||||
for (int i = 0; i < cn; i++)
|
||||
{
|
||||
dst[i].create(src.rows, src.cols, CV_MAKE_TYPE(src.depth(), 1));
|
||||
runner.addOutput(dst[i], ("y" + std::to_string(i)).c_str());
|
||||
}
|
||||
runner.addAttr(3, "split_dim").addAttr(cn, "num_split").run(stream);
|
||||
}
|
||||
|
||||
void split(const AscendMat& src, std::vector<AscendMat>& dst, AscendStream& stream)
|
||||
{
|
||||
dst.resize(src.channels());
|
||||
split(src, &dst[0], stream);
|
||||
}
|
||||
|
||||
void split(const InputArray _src, AscendMat* dst, AscendStream& stream)
|
||||
{
|
||||
AscendMat src;
|
||||
src.upload(_src, stream);
|
||||
split(src, dst, stream);
|
||||
}
|
||||
void split(const InputArray _src, std::vector<AscendMat>& dst, AscendStream& stream)
|
||||
{
|
||||
AscendMat src;
|
||||
src.upload(_src, stream);
|
||||
dst.resize(src.channels());
|
||||
split(_src, &dst[0], stream);
|
||||
}
|
||||
|
||||
void transpose(const AscendMat& src, int64_t* perm, AscendMat& dst, AscendStream& stream)
|
||||
{
|
||||
OperatorRunner runner;
|
||||
runner.setOp("TransposeD")
|
||||
.addInput(src, "x")
|
||||
.addOutput(dst, "y")
|
||||
.addAttr(perm, 4, "perm")
|
||||
.run(stream);
|
||||
}
|
||||
|
||||
void transpose(const AscendMat& src, AscendMat& dst, AscendStream& stream)
|
||||
{
|
||||
int64_t perm[] = {0, 2, 1, 3};
|
||||
dst.create(src.cols, src.rows, src.type());
|
||||
transpose(src, perm, dst, stream);
|
||||
}
|
||||
|
||||
void transpose(InputArray _src, OutputArray _dst, AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
transpose(src, dst, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
void flip(const AscendMat& src, std::vector<int32_t>& asixs, AscendMat& dst, AscendStream& stream)
|
||||
{
|
||||
int64_t dim = asixs.size();
|
||||
OperatorRunner runner;
|
||||
runner.setOp("ReverseV2")
|
||||
.addInput(src, "x")
|
||||
.addInput<int32_t>(&asixs.at(0), &dim, 1, ACL_INT32, "axis")
|
||||
.addOutput(dst, "y")
|
||||
.run(stream);
|
||||
}
|
||||
|
||||
void flip(const AscendMat& src, AscendMat& dst, int flipCode, AscendStream& stream)
|
||||
{
|
||||
std::vector<int32_t> asix;
|
||||
if (flipCode == 0)
|
||||
asix.push_back(1);
|
||||
else if (flipCode > 0)
|
||||
asix.push_back(2);
|
||||
else
|
||||
{
|
||||
asix.push_back(1);
|
||||
asix.push_back(2);
|
||||
}
|
||||
dst.create(src.rows, src.cols, src.type());
|
||||
flip(src, asix, dst, stream);
|
||||
}
|
||||
|
||||
void flip(const InputArray _src, OutputArray _dst, int flipCode, AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
flip(src, dst, flipCode, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
void rotate(const AscendMat& src, AscendMat& dst, int rotateMode, AscendStream& stream)
|
||||
{
|
||||
AscendMat tempMat;
|
||||
switch (rotateMode)
|
||||
{
|
||||
case ROTATE_90_CLOCKWISE:
|
||||
{
|
||||
dst.create(src.cols, src.rows, src.type());
|
||||
transpose(src, tempMat, stream);
|
||||
flip(tempMat, dst, 1, stream);
|
||||
break;
|
||||
}
|
||||
case ROTATE_180:
|
||||
{
|
||||
dst.create(src.rows, src.cols, src.type());
|
||||
flip(src, dst, -1, stream);
|
||||
break;
|
||||
}
|
||||
case ROTATE_90_COUNTERCLOCKWISE:
|
||||
{
|
||||
dst.create(src.cols, src.rows, src.type());
|
||||
transpose(src, tempMat, stream);
|
||||
flip(tempMat, dst, 0, stream);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rotate(InputArray _src, OutputArray _dst, int rotateMode, AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
rotate(src, dst, rotateMode, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
void crop(const AscendMat& src, AscendMat& dst, const AscendMat& sizeSrcNpu, int64_t* offset,
|
||||
AscendStream& stream)
|
||||
{
|
||||
OperatorRunner runner;
|
||||
runner.setOp("Crop")
|
||||
.addInput(src, "x")
|
||||
.addInput(sizeSrcNpu, "size")
|
||||
.addAttr(1, "axis")
|
||||
.addAttr(offset, 3, "offsets")
|
||||
.addOutput(dst, "y")
|
||||
.run(stream);
|
||||
}
|
||||
|
||||
AscendMat crop(const AscendMat& src, const Rect& rect, AscendStream& stream)
|
||||
{
|
||||
AscendMat dst, sizeSrcNpu;
|
||||
// left-up conner
|
||||
int x = rect.x, y = rect.y, width = rect.width, height = rect.height;
|
||||
int64_t offset[] = {y, x, 0};
|
||||
|
||||
CV_Assert(x + width <= src.cols && y + height <= src.rows);
|
||||
int size1[] = {1, src.channels(), height, width};
|
||||
dst.create(height, width, src.type());
|
||||
|
||||
Mat sizeSrc(height, width, src.type(), size1);
|
||||
sizeSrcNpu.upload(sizeSrc);
|
||||
crop(src, dst, sizeSrcNpu, offset, stream);
|
||||
|
||||
return dst;
|
||||
}
|
||||
AscendMat crop(InputArray _src, const Rect& rect, AscendStream& stream)
|
||||
{
|
||||
AscendMat src;
|
||||
src.upload(_src, stream);
|
||||
return crop(src, rect, stream);
|
||||
}
|
||||
|
||||
/************************** resize **************************/
|
||||
void checkResize(Size& ssize, Size& dsize, double inv_scale_x, double inv_scale_y,
|
||||
int& interpolation)
|
||||
{
|
||||
CV_Assert(!ssize.empty());
|
||||
float_t scaleX = (float_t)inv_scale_x;
|
||||
float_t scaleY = (float_t)inv_scale_y;
|
||||
// interpolation: resize mode, support bilinear/nearest neighbor/bicubic/pixel area relation.
|
||||
CV_Assert(interpolation == INTER_LINEAR || interpolation == INTER_NEAREST ||
|
||||
interpolation == INTER_CUBIC || interpolation == INTER_AREA);
|
||||
switch (interpolation)
|
||||
{
|
||||
case INTER_LINEAR:
|
||||
interpolation = INTER_NEAREST;
|
||||
break;
|
||||
case INTER_NEAREST:
|
||||
interpolation = INTER_LINEAR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (dsize.empty())
|
||||
{
|
||||
CV_Assert(scaleX > 0);
|
||||
CV_Assert(scaleY > 0);
|
||||
dsize = Size(saturate_cast<int>(ssize.width * inv_scale_x),
|
||||
saturate_cast<int>(ssize.height * inv_scale_y));
|
||||
CV_Assert(!dsize.empty());
|
||||
}
|
||||
else
|
||||
{
|
||||
scaleX = (float_t)dsize.width / ssize.width;
|
||||
scaleY = (float_t)dsize.height / ssize.height;
|
||||
CV_Assert(scaleX > 0);
|
||||
CV_Assert(scaleY > 0);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename inMat, typename outMat>
|
||||
void resize(const inMat& src, outMat& dst, int interpolation)
|
||||
{
|
||||
DvppOperatorDesc op;
|
||||
op.addInput(src).addOutput(dst);
|
||||
uint32_t taskID = 0;
|
||||
vpcResizeWarpper(op.chnId, op.inputDesc_[0].Pic, op.outputDesc_[0].Pic, interpolation, &taskID);
|
||||
|
||||
uint32_t taskIDResult = taskID;
|
||||
op.getResult(dst, taskIDResult);
|
||||
}
|
||||
void resize(const AscendMat& src, AscendMat& dst, int32_t* dstSize, int interpolation,
|
||||
AscendStream& stream)
|
||||
{
|
||||
OperatorRunner runner;
|
||||
int64_t dims[] = {2};
|
||||
char const* mode = "";
|
||||
switch (interpolation)
|
||||
{
|
||||
case INTER_CUBIC:
|
||||
mode = "ResizeBicubic";
|
||||
break;
|
||||
case INTER_AREA:
|
||||
mode = "ResizeArea";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
runner.setOp(mode)
|
||||
.addInput(src, "images")
|
||||
.addInput<int32_t>(dstSize, dims, 1, ACL_INT32, "size")
|
||||
.addAttr(true, "half_pixel_centers")
|
||||
.addOutput(dst, "y")
|
||||
.run(stream);
|
||||
}
|
||||
|
||||
void resize(const AscendMat& src, AscendMat& dst, Size dsize, double inv_scale_x,
|
||||
double inv_scale_y, int interpolation, AscendStream& stream)
|
||||
{
|
||||
Size ssize = src.size();
|
||||
checkResize(ssize, dsize, inv_scale_x, inv_scale_y, interpolation);
|
||||
int32_t dstSize[] = {dsize.height, dsize.width};
|
||||
dst.create(dstSize[0], dstSize[1], src.type());
|
||||
|
||||
if (interpolation == INTER_CUBIC || interpolation == INTER_AREA)
|
||||
{
|
||||
resize(src, dst, dstSize, interpolation, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
resize(src, dst, interpolation);
|
||||
}
|
||||
}
|
||||
|
||||
void resize(InputArray _src, OutputArray _dst, Size dsize, double inv_scale_x, double inv_scale_y,
|
||||
int interpolation, AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
if (interpolation == INTER_CUBIC || interpolation == INTER_AREA)
|
||||
{
|
||||
resize(src, dst, dsize, inv_scale_x, inv_scale_y, interpolation, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mat srcCV = _src.getMat();
|
||||
Size ssize = srcCV.size();
|
||||
checkResize(ssize, dsize, inv_scale_x, inv_scale_y, interpolation);
|
||||
_dst.create(dsize, srcCV.type());
|
||||
Mat dstCV = _dst.getMat();
|
||||
resize(srcCV, dstCV, interpolation);
|
||||
}
|
||||
}
|
||||
|
||||
/************************** CropResize **************************/
|
||||
template <typename inMat, typename outMat>
|
||||
void cropResize(const inMat& src, outMat& dst, const Rect& rect, Size dsize, int interpolation)
|
||||
{
|
||||
DvppOperatorDesc op;
|
||||
op.addInput(src).addOutput(dst);
|
||||
uint32_t taskID = 0;
|
||||
int cnt = 1;
|
||||
|
||||
vpcCropResizeWarpper(op.chnId, op.inputDesc_[0].Pic, op.outputDesc_[0].Pic, cnt, &taskID, rect,
|
||||
dsize, interpolation);
|
||||
|
||||
uint32_t taskIDResult = taskID;
|
||||
op.getResult(dst, taskIDResult);
|
||||
}
|
||||
|
||||
void cropResize(const AscendMat& src, AscendMat& dst, const Rect& rect, Size dsize,
|
||||
double inv_scale_x, double inv_scale_y, int interpolation)
|
||||
{
|
||||
Size ssize = src.size();
|
||||
checkResize(ssize, dsize, inv_scale_x, inv_scale_y, interpolation);
|
||||
dst.create(dsize.height, dsize.width, src.type());
|
||||
cropResize(src, dst, rect, dsize, interpolation);
|
||||
}
|
||||
|
||||
void cropResize(const InputArray _src, OutputArray _dst, const Rect& rect, Size dsize,
|
||||
double inv_scale_x, double inv_scale_y, int interpolation)
|
||||
{
|
||||
Size ssize = _src.size();
|
||||
checkResize(ssize, dsize, inv_scale_x, inv_scale_y, interpolation);
|
||||
|
||||
Mat src = _src.getMat();
|
||||
_dst.create(dsize.height, dsize.width, src.type());
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
cropResize(src, dst, rect, dsize, interpolation);
|
||||
}
|
||||
|
||||
/************************** CopyMakeBorder **************************/
|
||||
template <typename inMat, typename outMat>
|
||||
void copyMakeBorder(const inMat& src, outMat& dst, int* offsets, int borderType,
|
||||
const Scalar& value)
|
||||
{
|
||||
DvppOperatorDesc op;
|
||||
op.addInput(src).addOutput(dst);
|
||||
uint32_t taskID = 0;
|
||||
vpcCopyMakeBorderWarpper(op.chnId, op.inputDesc_[0].Pic, op.outputDesc_[0].Pic, &taskID,
|
||||
offsets, borderType, value);
|
||||
|
||||
uint32_t taskIDResult = taskID;
|
||||
op.getResult(dst, taskIDResult);
|
||||
}
|
||||
|
||||
void copyMakeBorder(const AscendMat& src, AscendMat& dst, int top, int bottom, int left, int right,
|
||||
int borderType, const Scalar& value)
|
||||
{
|
||||
dst.create(src.rows + top + bottom, src.cols + left + right, src.type());
|
||||
int offsets[] = {top, bottom, left, right};
|
||||
copyMakeBorder(src, dst, offsets, borderType, value);
|
||||
}
|
||||
|
||||
void copyMakeBorder(const InputArray _src, OutputArray _dst, int top, int bottom, int left,
|
||||
int right, int borderType, const Scalar& value)
|
||||
{
|
||||
CV_Assert(borderType < 2);
|
||||
Mat src = _src.getMat();
|
||||
_dst.create(src.rows + top + bottom, src.cols + left + right, src.type());
|
||||
Mat dst = _dst.getMat();
|
||||
int offsets[] = {top, bottom, left, right};
|
||||
|
||||
copyMakeBorder(src, dst, offsets, borderType, value);
|
||||
}
|
||||
|
||||
/************************** CropResizeMakeBorder **************************/
|
||||
|
||||
template <typename inMat, typename outMat>
|
||||
void cropResizeMakeBorder(const inMat& src, outMat& dst, const Rect& rect, Size dsize,
|
||||
int interpolation, int top, int left, const int borderType,
|
||||
Scalar scalarV)
|
||||
{
|
||||
DvppOperatorDesc op;
|
||||
op.addInput(src).addOutput(dst);
|
||||
uint32_t taskID = 0;
|
||||
int cnt = 1;
|
||||
vpcCropResizeMakeBorderWarpper(op.chnId, op.inputDesc_, op.outputDesc_, cnt, &taskID, rect,
|
||||
dsize, interpolation, borderType, scalarV, top, left);
|
||||
|
||||
uint32_t taskIDResult = taskID;
|
||||
op.getResult(dst, taskIDResult);
|
||||
}
|
||||
|
||||
void cropResizeMakeBorder(const AscendMat& src, AscendMat& dst, const Rect& rect, Size dsize,
|
||||
double inv_scale_x, double inv_scale_y, int interpolation, int top,
|
||||
int left, const int borderType, Scalar scalarV)
|
||||
{
|
||||
CV_Assert(borderType < 2);
|
||||
Size ssize = src.size();
|
||||
checkResize(ssize, dsize, inv_scale_x, inv_scale_y, interpolation);
|
||||
dst.create(dsize.height + top, dsize.width + left, src.type());
|
||||
|
||||
cropResizeMakeBorder(src, dst, rect, dsize, interpolation, top, left, borderType, scalarV);
|
||||
}
|
||||
|
||||
void cropResizeMakeBorder(const InputArray _src, OutputArray _dst, const Rect& rect, Size dsize,
|
||||
double inv_scale_x, double inv_scale_y, int interpolation, int top,
|
||||
int left, const int borderType, Scalar scalarV)
|
||||
{
|
||||
CV_Assert(borderType < 2);
|
||||
Size ssize = _src.size();
|
||||
checkResize(ssize, dsize, inv_scale_x, inv_scale_y, interpolation);
|
||||
|
||||
Mat src = _src.getMat();
|
||||
_dst.create(dsize.height + top, dsize.width + left, src.type());
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
cropResizeMakeBorder(src, dst, rect, dsize, interpolation, top, left, borderType, scalarV);
|
||||
}
|
||||
|
||||
} // namespace cann
|
||||
} // namespace cv
|
||||
@@ -0,0 +1,310 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include <acl/acl.h>
|
||||
#include <acl/dvpp/hi_dvpp.h>
|
||||
#include "opencv2/dvpp_call.hpp"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <cstdarg>
|
||||
#include <string>
|
||||
|
||||
#define unlikely(expr) __builtin_expect(!!(expr), 0)
|
||||
#define likely(expr) __builtin_expect(!!(expr), 1)
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace cann
|
||||
{
|
||||
|
||||
/******************************AscendPicDesc****************************/
|
||||
AscendPicDesc& AscendPicDesc::setMemAlign()
|
||||
{
|
||||
if (Pic.picture_format == HI_PIXEL_FORMAT_BGR_888 ||
|
||||
Pic.picture_format == HI_PIXEL_FORMAT_RGB_888 ||
|
||||
Pic.picture_format == HI_PIXEL_FORMAT_YUV_PACKED_444)
|
||||
{
|
||||
widthAlignment = 16;
|
||||
heightAlignment = 1;
|
||||
sizeAlignment = 3;
|
||||
sizeNum = 3;
|
||||
}
|
||||
else if (Pic.picture_format == HI_PIXEL_FORMAT_YUV_400)
|
||||
{
|
||||
widthAlignment = 16;
|
||||
heightAlignment = 1;
|
||||
sizeAlignment = 1;
|
||||
sizeNum = 1;
|
||||
}
|
||||
else if (Pic.picture_format == HI_PIXEL_FORMAT_ARGB_8888 ||
|
||||
Pic.picture_format == HI_PIXEL_FORMAT_ABGR_8888 ||
|
||||
Pic.picture_format == HI_PIXEL_FORMAT_RGBA_8888 ||
|
||||
Pic.picture_format == HI_PIXEL_FORMAT_BGRA_8888)
|
||||
{
|
||||
widthAlignment = 16;
|
||||
heightAlignment = 1;
|
||||
sizeAlignment = 4;
|
||||
sizeNum = 4;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
AscendPicDesc& AscendPicDesc::setPic(hi_pixel_format _picture_format)
|
||||
{
|
||||
// set input
|
||||
Pic.picture_format = _picture_format;
|
||||
setMemAlign();
|
||||
Pic.picture_width_stride = ALIGN_UP(Pic.picture_width, widthAlignment) * sizeAlignment;
|
||||
Pic.picture_height_stride = ALIGN_UP(Pic.picture_height, heightAlignment);
|
||||
Pic.picture_buffer_size =
|
||||
Pic.picture_width_stride * Pic.picture_height_stride * sizeAlignment / sizeNum;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::shared_ptr<hi_void> AscendPicDesc::allocate()
|
||||
{
|
||||
Pic.picture_address = nullptr;
|
||||
uint32_t ret = hi_mpi_dvpp_malloc(0, &Pic.picture_address, Pic.picture_buffer_size);
|
||||
if (ret != HI_SUCCESS)
|
||||
CV_Error(Error::StsBadFlag, "failed to malloc mem on dvpp");
|
||||
|
||||
return std::shared_ptr<hi_void>(Pic.picture_address, [](void* ptr) { hi_mpi_dvpp_free(ptr); });
|
||||
}
|
||||
|
||||
AscendPicDesc::AscendPicDesc(const AscendMat& ascendMat, hi_pixel_format _picture_format)
|
||||
{
|
||||
Pic.picture_width = ascendMat.cols;
|
||||
Pic.picture_height = ascendMat.rows;
|
||||
setPic(_picture_format);
|
||||
data = allocate();
|
||||
}
|
||||
|
||||
AscendPicDesc::AscendPicDesc(const Mat& mat, hi_pixel_format _picture_format)
|
||||
{
|
||||
Pic.picture_width = mat.cols;
|
||||
Pic.picture_height = mat.rows;
|
||||
setPic(_picture_format);
|
||||
data = allocate();
|
||||
}
|
||||
|
||||
/******************************hi_mpi_vpc warppers****************************/
|
||||
void vpcCropResizeWarpper(hi_vpc_chn chnId, hi_vpc_pic_info& inPic, hi_vpc_pic_info& outPic,
|
||||
int cnt, uint32_t* taskID, const Rect& rect, Size dsize,
|
||||
int interpolation)
|
||||
{
|
||||
hi_vpc_crop_region cropRegion = {.top_offset = static_cast<hi_u32>(rect.y),
|
||||
.left_offset = static_cast<hi_u32>(rect.x),
|
||||
.crop_width = static_cast<hi_u32>(rect.width),
|
||||
.crop_height = static_cast<hi_u32>(rect.height)};
|
||||
|
||||
hi_vpc_resize_info resize_info = {.resize_width = static_cast<hi_u32>(dsize.width),
|
||||
.resize_height = static_cast<hi_u32>(dsize.height),
|
||||
.interpolation = static_cast<hi_u32>(interpolation)};
|
||||
hi_vpc_crop_resize_region crop_resize_info[1];
|
||||
crop_resize_info[0].dest_pic_info = outPic;
|
||||
crop_resize_info[0].crop_region = cropRegion;
|
||||
crop_resize_info[0].resize_info = resize_info;
|
||||
uint32_t ret = hi_mpi_vpc_crop_resize(chnId, (const hi_vpc_pic_info*)&inPic, crop_resize_info,
|
||||
cnt, taskID, -1);
|
||||
if (ret != HI_SUCCESS)
|
||||
CV_Error(Error::StsBadFlag, "failed to crop and resize image");
|
||||
}
|
||||
|
||||
void vpcCopyMakeBorderWarpper(hi_vpc_chn chnId, hi_vpc_pic_info& inPic, hi_vpc_pic_info& outPic,
|
||||
uint32_t* taskID, int* offsets, int bordertype, Scalar value)
|
||||
{
|
||||
hi_vpc_make_border_info make_border_info;
|
||||
make_border_info = {.top = static_cast<hi_u32>(offsets[0]),
|
||||
.bottom = static_cast<hi_u32>(offsets[1]),
|
||||
.left = static_cast<hi_u32>(offsets[2]),
|
||||
.right = static_cast<hi_u32>(offsets[3]),
|
||||
.border_type = saturate_cast<hi_vpc_bord_type>(bordertype)};
|
||||
if (outPic.picture_format == HI_PIXEL_FORMAT_BGR_888)
|
||||
{
|
||||
make_border_info.scalar_value.val[0] = value[2];
|
||||
make_border_info.scalar_value.val[1] = value[1];
|
||||
make_border_info.scalar_value.val[2] = value[0];
|
||||
}
|
||||
else if (outPic.picture_format == HI_PIXEL_FORMAT_YUV_400)
|
||||
{
|
||||
make_border_info.scalar_value.val[0] = value[0];
|
||||
make_border_info.scalar_value.val[1] = value[1];
|
||||
make_border_info.scalar_value.val[2] = value[2];
|
||||
}
|
||||
make_border_info.scalar_value.val[3] = value[3];
|
||||
uint32_t ret = hi_mpi_vpc_copy_make_border(chnId, (const hi_vpc_pic_info*)&inPic, &outPic,
|
||||
make_border_info, taskID, -1);
|
||||
if (ret != HI_SUCCESS)
|
||||
CV_Error(Error::StsBadFlag, "failed to crop and resize image");
|
||||
}
|
||||
|
||||
void setBatchCropResizeMakeBorder(std::vector<AscendPicDesc>& outPicDesc,
|
||||
hi_vpc_crop_resize_border_region crop_resize_make_border_info[],
|
||||
const Rect& rect, Size dsize, int interpolation,
|
||||
const int borderType, Scalar scalarV, int top, int left,
|
||||
int batchSize)
|
||||
{
|
||||
hi_vpc_crop_region cropRegion = {.top_offset = static_cast<hi_u32>(rect.y),
|
||||
.left_offset = static_cast<hi_u32>(rect.x),
|
||||
.crop_width = static_cast<hi_u32>(rect.width),
|
||||
.crop_height = static_cast<hi_u32>(rect.height)};
|
||||
|
||||
hi_vpc_resize_info resize_info = {.resize_width = static_cast<hi_u32>(dsize.width),
|
||||
.resize_height = static_cast<hi_u32>(dsize.height),
|
||||
.interpolation = static_cast<hi_u32>(interpolation)};
|
||||
for (int i = 0; i < batchSize; i++)
|
||||
{
|
||||
crop_resize_make_border_info[i].dest_pic_info = outPicDesc[i].Pic;
|
||||
crop_resize_make_border_info[i].crop_region = cropRegion;
|
||||
crop_resize_make_border_info[i].resize_info = resize_info;
|
||||
crop_resize_make_border_info[i].dest_top_offset = top;
|
||||
crop_resize_make_border_info[i].dest_left_offset = left;
|
||||
crop_resize_make_border_info[i].border_type = static_cast<hi_vpc_bord_type>(borderType);
|
||||
if (crop_resize_make_border_info[i].dest_pic_info.picture_format == HI_PIXEL_FORMAT_BGR_888)
|
||||
{
|
||||
crop_resize_make_border_info[i].scalar_value.val[0] = scalarV[2];
|
||||
crop_resize_make_border_info[i].scalar_value.val[1] = scalarV[1];
|
||||
crop_resize_make_border_info[i].scalar_value.val[2] = scalarV[0];
|
||||
}
|
||||
else if (crop_resize_make_border_info[i].dest_pic_info.picture_format ==
|
||||
HI_PIXEL_FORMAT_YUV_400)
|
||||
{
|
||||
crop_resize_make_border_info[i].scalar_value.val[0] = scalarV[0];
|
||||
crop_resize_make_border_info[i].scalar_value.val[1] = scalarV[1];
|
||||
crop_resize_make_border_info[i].scalar_value.val[2] = scalarV[2];
|
||||
}
|
||||
crop_resize_make_border_info[i].scalar_value.val[3] = scalarV[3];
|
||||
}
|
||||
}
|
||||
|
||||
void vpcCropResizeMakeBorderWarpper(hi_vpc_chn chnId, std::vector<AscendPicDesc>& inPicDesc,
|
||||
std::vector<AscendPicDesc>& outPicDesc, int cnt,
|
||||
uint32_t* taskID, const Rect& rect, Size dsize,
|
||||
int interpolation, const int borderType, Scalar scalarV,
|
||||
int top, int left)
|
||||
{
|
||||
hi_vpc_crop_resize_border_region crop_resize_make_border_info[1];
|
||||
|
||||
setBatchCropResizeMakeBorder(outPicDesc, crop_resize_make_border_info, rect, dsize,
|
||||
interpolation, borderType, scalarV, top, left, 1);
|
||||
uint32_t ret =
|
||||
hi_mpi_vpc_crop_resize_make_border(chnId, (const hi_vpc_pic_info*)&inPicDesc[0].Pic,
|
||||
crop_resize_make_border_info, cnt, taskID, -1);
|
||||
if (ret != HI_SUCCESS)
|
||||
CV_Error(Error::StsBadFlag, "failed to crop, resize and make border of image");
|
||||
}
|
||||
|
||||
/******************************DvppOperatorDesc****************************/
|
||||
DvppOperatorDesc& DvppOperatorDesc::reset()
|
||||
{
|
||||
uint32_t ret = hi_mpi_vpc_destroy_chn(chnId);
|
||||
if (ret != HI_SUCCESS)
|
||||
CV_Error(Error::StsBadFlag, "failed to destory DVPP vpc channel");
|
||||
inputDesc_.clear();
|
||||
outputDesc_.clear();
|
||||
holder.clear();
|
||||
return *this;
|
||||
}
|
||||
void initDvpp() { hi_mpi_sys_init(); }
|
||||
|
||||
void finalizeDvpp() { hi_mpi_sys_exit(); }
|
||||
|
||||
DvppOperatorDesc& DvppOperatorDesc::createChannel()
|
||||
{
|
||||
uint32_t ret = hi_mpi_vpc_sys_create_chn(&chnId, &stChnAttr);
|
||||
if (ret != HI_SUCCESS)
|
||||
CV_Error(Error::StsBadFlag, "failed to create DVPP vpc channel");
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy input array to dvpp memory
|
||||
DvppOperatorDesc& DvppOperatorDesc::addInput(AscendPicDesc& picDesc)
|
||||
{
|
||||
inputDesc_.push_back(picDesc);
|
||||
holder.insert(picDesc.data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename inMat>
|
||||
hi_pixel_format setPixelFormat(const inMat& mat)
|
||||
{
|
||||
CV_Assert(mat.channels() == 3 || mat.channels() == 1);
|
||||
hi_pixel_format _picture_format;
|
||||
if (mat.channels() == 3)
|
||||
{
|
||||
_picture_format = HI_PIXEL_FORMAT_BGR_888;
|
||||
}
|
||||
else if (mat.channels() == 1)
|
||||
{
|
||||
_picture_format = HI_PIXEL_FORMAT_YUV_400;
|
||||
}
|
||||
return _picture_format;
|
||||
}
|
||||
|
||||
DvppOperatorDesc& DvppOperatorDesc::addInput(const AscendMat& mat)
|
||||
{
|
||||
Mat matHost;
|
||||
mat.download(matHost);
|
||||
return addInput(matHost);
|
||||
}
|
||||
|
||||
DvppOperatorDesc& DvppOperatorDesc::addInput(const Mat& mat)
|
||||
{
|
||||
hi_pixel_format _picture_format = setPixelFormat(mat);
|
||||
|
||||
AscendPicDesc picDesc(mat, _picture_format);
|
||||
aclrtMemcpy2d(picDesc.Pic.picture_address, picDesc.Pic.picture_width_stride, mat.data,
|
||||
mat.step[0], mat.step[0], picDesc.Pic.picture_height, ACL_MEMCPY_HOST_TO_DEVICE);
|
||||
|
||||
return addInput(picDesc);
|
||||
}
|
||||
|
||||
// malloc memory for output
|
||||
DvppOperatorDesc& DvppOperatorDesc::addOutput(AscendPicDesc& picDesc)
|
||||
{
|
||||
outputDesc_.push_back(picDesc);
|
||||
holder.insert(picDesc.data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DvppOperatorDesc& DvppOperatorDesc::addOutput(AscendMat& mat)
|
||||
{
|
||||
hi_pixel_format _picture_format = setPixelFormat(mat);
|
||||
AscendPicDesc picDesc(mat, _picture_format);
|
||||
return addOutput(picDesc);
|
||||
}
|
||||
|
||||
DvppOperatorDesc& DvppOperatorDesc::addOutput(Mat& mat)
|
||||
{
|
||||
hi_pixel_format _picture_format = setPixelFormat(mat);
|
||||
AscendPicDesc picDesc(mat, _picture_format);
|
||||
return addOutput(picDesc);
|
||||
}
|
||||
|
||||
// get process result and copy it to host/device
|
||||
DvppOperatorDesc& DvppOperatorDesc::getResult(Mat& dst, uint32_t& taskIDResult)
|
||||
{
|
||||
uint32_t ret = hi_mpi_vpc_get_process_result(chnId, taskIDResult, -1);
|
||||
if (ret != HI_SUCCESS)
|
||||
CV_Error(Error::StsBadFlag, "failed to get process result.");
|
||||
const uint32_t esz = CV_ELEM_SIZE(dst.type());
|
||||
size_t step = esz * dst.cols;
|
||||
|
||||
aclrtMemcpy2d(dst.data, dst.step[0], outputDesc_[0].Pic.picture_address,
|
||||
outputDesc_[0].Pic.picture_width_stride, dst.step[0],
|
||||
outputDesc_[0].Pic.picture_height, ACL_MEMCPY_DEVICE_TO_HOST);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DvppOperatorDesc& DvppOperatorDesc::getResult(AscendMat& dst, uint32_t& taskIDResult)
|
||||
{
|
||||
Mat matHost;
|
||||
matHost.create(dst.rows, dst.cols, dst.type());
|
||||
getResult(matHost, taskIDResult);
|
||||
dst.upload(matHost);
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace cann
|
||||
} // namespace cv
|
||||
@@ -0,0 +1,471 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace cann
|
||||
{
|
||||
|
||||
static inline void applyMask(const AscendMat& src, AscendMat& dst, const AscendMat& mask,
|
||||
AscendStream& stream)
|
||||
{
|
||||
int mtype = mask.type();
|
||||
CV_Assert((mtype == CV_8UC1 || mtype == CV_8SC1) && mask.size() == src.size());
|
||||
AscendMat onesMask, castedMask;
|
||||
onesMask.create(mask.rows, mask.cols, mask.type());
|
||||
|
||||
OperatorRunner runner;
|
||||
runner.setOp("Div")
|
||||
.addInput(mask, "x1")
|
||||
.addInput(mask, "x2")
|
||||
.addOutput(onesMask, "y")
|
||||
.run(stream);
|
||||
|
||||
onesMask.convertTo(castedMask, dst.depth(), stream);
|
||||
arithm_op(src, castedMask, dst, "Mul", stream);
|
||||
}
|
||||
|
||||
static inline void applyScale(const AscendMat& src, AscendMat& dst, float scale,
|
||||
AscendStream& stream)
|
||||
{
|
||||
OperatorRunner runner;
|
||||
arithm_op(src, scale, dst, "Muls", stream);
|
||||
}
|
||||
|
||||
void arithm_op(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const char* op,
|
||||
AscendStream& stream)
|
||||
{
|
||||
if (src2.empty())
|
||||
arithm_op(src1, dst, op, stream);
|
||||
else
|
||||
{
|
||||
OperatorRunner runner;
|
||||
runner.setOp(op).addInput(src1, "x1").addInput(src2, "x2").addOutput(dst, "y").run(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void arithm_op(const AscendMat& src, const Scalar& sc, AscendMat& dst, const char* op,
|
||||
AscendStream& stream)
|
||||
{
|
||||
OperatorRunner runner;
|
||||
runner.setOp(op)
|
||||
.addInput(src, "x1")
|
||||
.addInput(sc, src.type(), "x2")
|
||||
.addOutput(dst, "y")
|
||||
.run(stream);
|
||||
}
|
||||
|
||||
void arithm_op(const Scalar& sc, const AscendMat& src, AscendMat& dst, const char* op,
|
||||
AscendStream& stream)
|
||||
{
|
||||
OperatorRunner runner;
|
||||
runner.setOp(op)
|
||||
.addInput(sc, src.type(), "x1")
|
||||
.addInput(src, "x2")
|
||||
.addOutput(dst, "y")
|
||||
.run(stream);
|
||||
}
|
||||
|
||||
void arithm_op(const AscendMat& src, AscendMat& dst, const char* op, AscendStream& stream)
|
||||
{
|
||||
OperatorRunner runner;
|
||||
runner.setOp(op).addInput(src, "x").addOutput(dst, "y").run(stream);
|
||||
}
|
||||
|
||||
void arithm_op(const AscendMat& src, float scalar, AscendMat& dst, const char* op,
|
||||
AscendStream& stream)
|
||||
{
|
||||
OperatorRunner runner;
|
||||
runner.setOp(op).addInput(src, "x").addAttr(scalar, "value").addOutput(dst, "y").run(stream);
|
||||
}
|
||||
|
||||
// Helper function for template arithm_op. all function called in template arithm_op should be
|
||||
// done in both AscendMat and Scalar.
|
||||
static void getInputInfo(const AscendMat& src, int& depth, int& cn, Size& size)
|
||||
{
|
||||
depth = src.depth();
|
||||
cn = src.channels();
|
||||
size = src.size();
|
||||
}
|
||||
|
||||
static void getInputInfo(const Scalar& src, int& depth, int& cn, Size& size)
|
||||
{
|
||||
CV_UNUSED(src);
|
||||
depth = -1;
|
||||
cn = -1;
|
||||
size = {-1, -1};
|
||||
}
|
||||
|
||||
static void convert(const AscendMat& src, AscendMat& dst, AscendStream& stream)
|
||||
{
|
||||
src.convertTo(dst, CV_32F, stream);
|
||||
}
|
||||
|
||||
static void convert(const Scalar& src, Scalar& dst, AscendStream& stream)
|
||||
{
|
||||
CV_UNUSED(stream);
|
||||
dst = src;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
static void arithm_op(const T1& src1, const T2& src2, AscendMat& dst, const AscendMat& mask,
|
||||
float scale, int dtype, const char* op, AscendStream& stream)
|
||||
{
|
||||
T1 castedSrc1;
|
||||
T2 castedSrc2;
|
||||
AscendMat castedRet;
|
||||
|
||||
int sdepth1, sdepth2, scn1, scn2;
|
||||
Size ssize1, ssize2;
|
||||
getInputInfo(src1, sdepth1, scn1, ssize1);
|
||||
getInputInfo(src2, sdepth2, scn2, ssize2);
|
||||
|
||||
int sdepth = sdepth1 == -1 ? sdepth2 : sdepth1;
|
||||
int cn = scn1 == -1 ? scn2 : scn1;
|
||||
Size size = sdepth1 == -1 ? ssize2 : ssize1;
|
||||
|
||||
if (sdepth1 != -1 && sdepth2 != -1 && !ssize1.empty() && !ssize2.empty())
|
||||
CV_Assert(sdepth1 == sdepth2 && scn1 == scn2 && ssize1 == ssize2);
|
||||
|
||||
if (dtype < 0)
|
||||
dtype = sdepth;
|
||||
const int ddepth = CV_MAT_DEPTH(dtype);
|
||||
CV_Assert(sdepth <= CV_16F && ddepth <= CV_16F);
|
||||
|
||||
dst.create(size.height, size.width, CV_MAKE_TYPE(ddepth, cn));
|
||||
|
||||
// In order to achieve high accuracy, convert integers to float for calculation.
|
||||
if (scale != 1 && dtype < CV_32F)
|
||||
{
|
||||
convert(src1, castedSrc1, stream);
|
||||
convert(src2, castedSrc2, stream);
|
||||
castedRet.create(size.height, size.width, CV_MAKE_TYPE(CV_32F, cn));
|
||||
}
|
||||
else
|
||||
{
|
||||
castedSrc1 = src1;
|
||||
castedSrc2 = src2;
|
||||
castedRet = dst;
|
||||
}
|
||||
|
||||
// step1, calculate operator.
|
||||
OperatorRunner runner;
|
||||
arithm_op(castedSrc1, castedSrc2, castedRet, op, stream);
|
||||
|
||||
// step2, apply mask if need.
|
||||
if (!mask.empty())
|
||||
applyMask(castedRet, castedRet, mask, stream);
|
||||
|
||||
// step3, apply scale if need.
|
||||
if (scale != 1)
|
||||
applyScale(castedRet, castedRet, scale, stream);
|
||||
|
||||
// After rounding the result, convert the type to the original type.
|
||||
if (castedRet.depth() != dst.depth())
|
||||
{
|
||||
runner.setOp("Round").addInput(castedRet, "x").addOutput(castedRet, "y").run(stream);
|
||||
castedRet.convertTo(dst, stream);
|
||||
}
|
||||
}
|
||||
|
||||
static void arithm_op(const InputArray _src1, const InputArray _src2, OutputArray _dst,
|
||||
const InputArray _mask, float scale, int dtype, const char* op,
|
||||
AscendStream& stream)
|
||||
{
|
||||
const bool isScalar1 = (_src1.kind() == _InputArray::MATX);
|
||||
const bool isScalar2 = (_src2.kind() == _InputArray::MATX);
|
||||
|
||||
if (isScalar1 && isScalar2)
|
||||
CV_Error(Error::StsBadArg, "At list one matrix parameter shoule be passwd.");
|
||||
|
||||
AscendMat src1, src2, dst, mask;
|
||||
Mat scalar;
|
||||
|
||||
if (!isScalar1 && !_src1.empty())
|
||||
src1.upload(_src1, stream);
|
||||
if (!isScalar2 && !_src2.empty())
|
||||
src2.upload(_src2, stream);
|
||||
|
||||
if (!_mask.empty())
|
||||
mask.upload(_mask, stream);
|
||||
|
||||
Scalar val;
|
||||
if (isScalar1)
|
||||
scalar = _src1.getMat();
|
||||
else if (isScalar2)
|
||||
scalar = _src2.getMat();
|
||||
|
||||
if (!scalar.empty())
|
||||
{
|
||||
CV_Assert(scalar.total() <= 4);
|
||||
scalar.convertTo(Mat_<double>(scalar.rows, scalar.cols, &val[0]), CV_64F);
|
||||
}
|
||||
|
||||
if (isScalar1)
|
||||
arithm_op(val, src2, dst, mask, scale, dtype, op, stream);
|
||||
else if (isScalar2)
|
||||
arithm_op(src1, val, dst, mask, scale, dtype, op, stream);
|
||||
else
|
||||
arithm_op(src1, src2, dst, mask, scale, dtype, op, stream);
|
||||
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
// In order to supply more interfaces, differnet function declaration shoule be done.
|
||||
void add(const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask,
|
||||
int dtype, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, dtype, "Add", stream);
|
||||
}
|
||||
|
||||
void add(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask,
|
||||
int dtype, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, dtype, "Add", stream);
|
||||
}
|
||||
|
||||
void add(const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask,
|
||||
int dtype, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, dtype, "Add", stream);
|
||||
}
|
||||
|
||||
void add(const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask,
|
||||
int dtype, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, dtype, "Add", stream);
|
||||
}
|
||||
|
||||
void subtract(const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask,
|
||||
int dtype, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, dtype, "Sub", stream);
|
||||
}
|
||||
|
||||
void subtract(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask,
|
||||
int dtype, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, dtype, "Sub", stream);
|
||||
}
|
||||
|
||||
void subtract(const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask,
|
||||
int dtype, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, dtype, "Sub", stream);
|
||||
}
|
||||
|
||||
void subtract(const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask,
|
||||
int dtype, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, dtype, "Sub", stream);
|
||||
}
|
||||
|
||||
void multiply(const InputArray src1, const InputArray src2, OutputArray dst, float scale, int dtype,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, noArray(), scale, dtype, "Mul", stream);
|
||||
}
|
||||
|
||||
void multiply(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "Mul", stream);
|
||||
}
|
||||
|
||||
void multiply(const AscendMat& src1, const Scalar& src2, AscendMat& dst, float scale, int dtype,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "Mul", stream);
|
||||
}
|
||||
|
||||
void multiply(const Scalar& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "Mul", stream);
|
||||
}
|
||||
|
||||
void divide(const InputArray src1, const InputArray src2, OutputArray dst, float scale, int dtype,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, noArray(), scale, dtype, "RealDiv", stream);
|
||||
}
|
||||
|
||||
void divide(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "RealDiv", stream);
|
||||
}
|
||||
|
||||
void divide(const AscendMat& src1, const Scalar& src2, AscendMat& dst, float scale, int dtype,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "RealDiv", stream);
|
||||
}
|
||||
|
||||
void divide(const Scalar& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "RealDiv", stream);
|
||||
}
|
||||
|
||||
void bitwise_and(const InputArray src1, const InputArray src2, OutputArray dst,
|
||||
const InputArray mask, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseAnd", stream);
|
||||
}
|
||||
|
||||
void bitwise_and(const AscendMat& src1, const AscendMat& src2, AscendMat& dst,
|
||||
const AscendMat& mask, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseAnd", stream);
|
||||
}
|
||||
|
||||
void bitwise_and(const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseAnd", stream);
|
||||
}
|
||||
|
||||
void bitwise_and(const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseAnd", stream);
|
||||
}
|
||||
|
||||
void bitwise_or(const InputArray src1, const InputArray src2, OutputArray dst,
|
||||
const InputArray mask, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseOr", stream);
|
||||
}
|
||||
|
||||
void bitwise_or(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseOr", stream);
|
||||
}
|
||||
|
||||
void bitwise_or(const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseOr", stream);
|
||||
}
|
||||
|
||||
void bitwise_or(const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseOr", stream);
|
||||
}
|
||||
|
||||
void bitwise_xor(const InputArray src1, const InputArray src2, OutputArray dst,
|
||||
const InputArray mask, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseXor", stream);
|
||||
}
|
||||
|
||||
void bitwise_xor(const AscendMat& src1, const AscendMat& src2, AscendMat& dst,
|
||||
const AscendMat& mask, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseXor", stream);
|
||||
}
|
||||
|
||||
void bitwise_xor(const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseXor", stream);
|
||||
}
|
||||
|
||||
void bitwise_xor(const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask,
|
||||
AscendStream& stream)
|
||||
{
|
||||
arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseXor", stream);
|
||||
}
|
||||
|
||||
void bitwise_not(const InputArray src, OutputArray dst, const InputArray mask, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src, noArray(), dst, mask, 1, -1, "Invert", stream);
|
||||
}
|
||||
|
||||
void bitwise_not(const AscendMat& src, AscendMat& dst, const AscendMat& mask, AscendStream& stream)
|
||||
{
|
||||
arithm_op(src, AscendMat(), dst, mask, 1, -1, "Invert", stream);
|
||||
}
|
||||
|
||||
void addWeighted(const AscendMat& src1, double alpha, const AscendMat& src2, double beta,
|
||||
double gamma, AscendMat& dst, int dtype, AscendStream& stream)
|
||||
{
|
||||
if (dtype < 0)
|
||||
dtype = src1.depth();
|
||||
|
||||
CV_Assert(src2.depth() == src1.depth() && src2.size() == src1.size() &&
|
||||
src1.channels() == src2.channels());
|
||||
|
||||
int type = CV_MAKE_TYPE(dtype, src1.channels());
|
||||
dst.create(src1.rows, src1.cols, type);
|
||||
|
||||
// TODO: Consider overflow, should extend type or not?
|
||||
AscendMat src1Weighted(src1.size(), type), src2Weighted(src1.size(), type),
|
||||
srcWeightedSumRet(src1.size(), type);
|
||||
|
||||
arithm_op(src1, (float)alpha, src1Weighted, "Muls", stream);
|
||||
arithm_op(src2, (float)beta, src2Weighted, "Muls", stream);
|
||||
arithm_op(src1Weighted, src2Weighted, srcWeightedSumRet, "Add", stream);
|
||||
arithm_op(srcWeightedSumRet, (float)gamma, dst, "Adds", stream);
|
||||
}
|
||||
|
||||
void addWeighted(const InputArray _src1, double alpha, const InputArray _src2, double beta,
|
||||
double gamma, OutputArray _dst, int dtype, AscendStream& stream)
|
||||
{
|
||||
AscendMat src1, src2, dst;
|
||||
src1.upload(_src1, stream);
|
||||
src2.upload(_src2, stream);
|
||||
addWeighted(src1, alpha, src2, beta, gamma, dst, dtype, stream);
|
||||
dst.download(_dst, stream);
|
||||
}
|
||||
|
||||
double threshold(const AscendMat& src, AscendMat& dst, double thresh, double maxval, int type,
|
||||
AscendStream& stream)
|
||||
{
|
||||
// ThresholdTypes is defined in opencv2/imgproc, This type is the only Symbol we need.
|
||||
// Add imgproc to dependence is too heavy, use magic number instead.
|
||||
CV_Assert(type <= 4 /*THRESH_TOZERO_INV*/);
|
||||
|
||||
AscendMat threshMat(src.size(), src.type());
|
||||
|
||||
dst.create(src.rows, src.cols, src.type());
|
||||
|
||||
if (src.depth() == CV_8U || src.depth() == CV_8S || src.depth() == CV_16S ||
|
||||
src.depth() == CV_32S || src.depth() == CV_32F || src.depth() == CV_16F)
|
||||
{
|
||||
ThresholdOpencvTilingData tiling;
|
||||
tiling.maxVal = maxval;
|
||||
tiling.thresh = thresh;
|
||||
// AscendMat memory will be align to 32B, it's safe to set totalLengh a little bigger.
|
||||
size_t totalBytes = src.rows * src.cols * src.channels();
|
||||
tiling.totalLength = ALIGN_UP(totalBytes, 32);
|
||||
tiling.threshType = type;
|
||||
tiling.dtype = src.depth();
|
||||
|
||||
kernel_launch(aclrtlaunch_threshold_opencv, stream, tiling, src.data.get(), dst.data.get());
|
||||
}
|
||||
else
|
||||
CV_Error(Error::StsUnsupportedFormat, "");
|
||||
|
||||
return thresh;
|
||||
}
|
||||
|
||||
double threshold(const InputArray _src, OutputArray _dst, double thresh, double maxval, int type,
|
||||
AscendStream& stream)
|
||||
{
|
||||
AscendMat src, dst;
|
||||
src.upload(_src, stream);
|
||||
dst.create(src.rows, src.cols, src.type());
|
||||
double ret = threshold(src, dst, thresh, maxval, type, stream);
|
||||
dst.download(_dst, stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace cann
|
||||
} // namespace cv
|
||||
@@ -0,0 +1,17 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef __OPENCV_PRECOMP_H__
|
||||
#define __OPENCV_PRECOMP_H__
|
||||
|
||||
#include "opencv2/cann.hpp"
|
||||
#include "opencv2/stream_accessor.hpp"
|
||||
#include "opencv2/cann_call.hpp"
|
||||
#include "opencv2/cann_interface.hpp"
|
||||
#include "opencv2/cann_private.hpp"
|
||||
#include "opencv2/dvpp_call.hpp"
|
||||
#include "opencv2/ascendc_kernels.hpp"
|
||||
#define ALIGN_UP(num, align) (((num) + (align) - 1) & ~((align) - 1))
|
||||
|
||||
#endif /* __OPENCV_PRECOMP_H__ */
|
||||
Reference in New Issue
Block a user