2025-09-08 03:47:12 +09:00

379 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# include <iostream>
# include <fstream>
# include <opencv2/dnn.hpp>
# include <opencv2/imgproc.hpp>
# include <opencv2/imgcodecs.hpp>
# include <opencv2/dnn/layer.details.hpp>
# include <opencv2/dnn/all_layers.hpp>
#define CV_VERSION_STR CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION)
// ƒrƒƒhƒ<C692>[ƒh
#ifdef _DEBUG
#define CV_EXT_STR "d.lib"
#else
#define CV_EXT_STR ".lib"
#endif
#ifdef _MSC_VER
#pragma comment(lib, "opencv_core" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_imgcodecs" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_imgproc" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_dnn" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "libprotobuf" CV_EXT_STR)
#pragma comment(lib, "IlmImf" CV_EXT_STR)
#pragma comment(lib, "libjpeg-turbo" CV_EXT_STR)
#pragma comment(lib, "libopenjp2" CV_EXT_STR)
#pragma comment(lib, "libpng" CV_EXT_STR)
#pragma comment(lib, "libtiff" CV_EXT_STR)
#pragma comment(lib, "libwebp" CV_EXT_STR)
#pragma comment(lib, "zlib" CV_EXT_STR)
#pragma comment(lib, "cudart.lib")
//#pragma comment(lib, "curand.lib")
#pragma comment(lib, "cublas.lib")
#pragma comment(lib, "cudnn.lib")
#endif
using namespace std;
class CropCenterLayer : public cv::dnn::Layer
{
private:
std::vector<int> cropSize;
cv::Ptr<cv::dnn::Layer> cropLayer;
public:
CropCenterLayer(const cv::dnn::LayerParams& params) : Layer(params)
{
setParamsFrom(params);
if (params.has("crop_size"))
{
const auto& paramCropSize = params.get("crop_size");
const auto& str = paramCropSize.getStringValue();
const int s = atoi(str.c_str());
cropSize.resize(4);
cropSize[0] = 0;
cropSize[1] = 0;
cropSize[2] = s;
cropSize[3] = s;
}
cv::dnn::LayerParams parasm;
parasm.set("axis", 0);
parasm.set("offset", cv::dnn::DictValue::arrayInt(cropSize.data(), cropSize.size()));
cropLayer = cv::dnn::CropLayer::create(parasm);
}
// Destructor
virtual ~CropCenterLayer() = default;
static cv::Ptr<cv::dnn::Layer> create(cv::dnn::LayerParams& params)
{
return cv::Ptr<CropCenterLayer>(new CropCenterLayer(params));
}
// Override virtual functions from cv::dnn::Layer and delegate to cropLayer
CV_DEPRECATED_EXTERNAL virtual void finalize(const std::vector<cv::Mat*>& input, std::vector<cv::Mat>& output) override
{
cropLayer->finalize(input, output);
}
virtual void finalize(cv::InputArrayOfArrays inputs_arr, cv::OutputArrayOfArrays outputs_arr) override
{
std::vector<cv::Mat> inputs;
inputs_arr.getMatVector(inputs);
CV_Assert(inputs.size() == 1);
const auto& input = inputs[0];
//cv::Mat sizeShape(input.dims, input.size.p, input.type());
cv::Mat sizeShape(input.size.dims(), input.size.p, input.type());
auto& sz = sizeShape.size;
for (int i = 0; i < sz.dims(); i++)
{
sz[i] = sz[i] - cropSize[i] * 2;
CV_Assert(sz[i] >= 0);
}
inputs.push_back(sizeShape); // dummy second input for CropLayer
cropLayer->finalize(inputs, outputs_arr);
}
CV_DEPRECATED_EXTERNAL virtual void forward(std::vector<cv::Mat*>& input, std::vector<cv::Mat>& output, std::vector<cv::Mat>& internals)
{
cropLayer->forward(input, output, internals);
}
virtual void forward(cv::InputArrayOfArrays inputs, cv::OutputArrayOfArrays outputs, cv::OutputArrayOfArrays internals) override
{
cropLayer->forward(inputs, outputs, internals);
}
virtual bool tryQuantize(const std::vector<std::vector<float>>& scales,
const std::vector<std::vector<int>>& zeropoints, cv::dnn::LayerParams& params) override
{
return cropLayer->tryQuantize(scales, zeropoints, params);
}
CV_DEPRECATED_EXTERNAL void finalize(const std::vector<cv::Mat>& inputs, CV_OUT std::vector<cv::Mat>& outputs)
{
cropLayer->finalize(inputs, outputs);
}
CV_DEPRECATED std::vector<cv::Mat> finalize(const std::vector<cv::Mat>& inputs)
{
cropLayer->finalize(inputs);
}
CV_DEPRECATED CV_WRAP void run(const std::vector<cv::Mat>& inputs, CV_OUT std::vector<cv::Mat>& outputs,
CV_IN_OUT std::vector<cv::Mat>& internals)
{
cropLayer->run(inputs, outputs, internals);
}
virtual int inputNameToIndex(cv::String inputName) override
{
return cropLayer->inputNameToIndex(inputName);
}
virtual int outputNameToIndex(const cv::String& outputName) override
{
return cropLayer->outputNameToIndex(outputName);
}
virtual bool supportBackend(int backendId) override
{
return cropLayer->supportBackend(backendId);
}
virtual cv::Ptr<cv::dnn::BackendNode> initHalide(const std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& inputs) override
{
// preferableTarget𔽉f³¹éƒ^ƒCƒ~ƒ“ƒOª±±µ©È¢ÁÛ¢ÌÅ”½‰f³¹é
cropLayer->preferableTarget = preferableTarget;
return cropLayer->initHalide(inputs);
}
virtual cv::Ptr<cv::dnn::BackendNode> initNgraph(const std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& inputs,
const std::vector<cv::Ptr<cv::dnn::BackendNode>>& nodes) override
{
// preferableTarget𔽉f³¹éƒ^ƒCƒ~ƒ“ƒOª±±µ©È¢ÁÛ¢ÌÅ”½‰f³¹é
cropLayer->preferableTarget = preferableTarget;
return cropLayer->initNgraph(inputs, nodes);
}
virtual cv::Ptr<cv::dnn::BackendNode> initVkCom(const std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& inputs,
std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& outputs) override
{
// preferableTarget𔽉f³¹éƒ^ƒCƒ~ƒ“ƒOª±±µ©È¢ÁÛ¢ÌÅ”½‰f³¹é
cropLayer->preferableTarget = preferableTarget;
return cropLayer->initVkCom(inputs, outputs);
}
virtual cv::Ptr<cv::dnn::BackendNode> initWebnn(const std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& inputs,
const std::vector<cv::Ptr<cv::dnn::BackendNode>>& nodes) override
{
// preferableTarget𔽉f³¹éƒ^ƒCƒ~ƒ“ƒOª±±µ©È¢ÁÛ¢ÌÅ”½‰f³¹é
cropLayer->preferableTarget = preferableTarget;
return cropLayer->initWebnn(inputs, nodes);
}
virtual cv::Ptr<cv::dnn::BackendNode> initCUDA(void* context,
const std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& inputs,
const std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& outputs) override
{
// preferableTarget𔽉f³¹éƒ^ƒCƒ~ƒ“ƒOª±±µ©È¢ÁÛ¢ÌÅ”½‰f³¹é
cropLayer->preferableTarget = preferableTarget;
return cropLayer->initCUDA(context, inputs, outputs);
}
virtual cv::Ptr<cv::dnn::BackendNode> initTimVX(void* timVxInfo,
const std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& inputsWrapper,
const std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& outputsWrapper,
bool isLast) override
{
// preferableTarget𔽉f³¹éƒ^ƒCƒ~ƒ“ƒOª±±µ©È¢ÁÛ¢ÌÅ”½‰f³¹é
cropLayer->preferableTarget = preferableTarget;
return cropLayer->initTimVX(timVxInfo, inputsWrapper, outputsWrapper, isLast);
}
virtual cv::Ptr<cv::dnn::BackendNode> initCann(const std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& inputs,
const std::vector<cv::Ptr<cv::dnn::BackendWrapper>>& outputs,
const std::vector<cv::Ptr<cv::dnn::BackendNode>>& nodes) override
{
// preferableTarget𔽉f³¹éƒ^ƒCƒ~ƒ“ƒOª±±µ©È¢ÁÛ¢ÌÅ”½‰f³¹é
cropLayer->preferableTarget = preferableTarget;
return cropLayer->initCann(inputs, outputs, nodes);
}
virtual void applyHalideScheduler(cv::Ptr<cv::dnn::BackendNode>& node,
const std::vector<cv::Mat*>& inputs,
const std::vector<cv::Mat>& outputs,
int targetId) const override
{
cropLayer->applyHalideScheduler(node, inputs, outputs, targetId);
}
virtual cv::Ptr<cv::dnn::BackendNode> tryAttach(const cv::Ptr<cv::dnn::BackendNode>& node) override
{
return cropLayer->tryAttach(node);
}
virtual bool setActivation(const cv::Ptr<cv::dnn::ActivationLayer>& layer) override
{
return cropLayer->setActivation(layer);
}
virtual bool tryFuse(cv::Ptr<cv::dnn::Layer>& top) override
{
return cropLayer->tryFuse(top);
}
virtual void getScaleShift(cv::Mat& scale, cv::Mat& shift) const override
{
cropLayer->getScaleShift(scale, shift);
}
virtual void getScaleZeropoint(float& scale, int& zeropoint) const override
{
cropLayer->getScaleZeropoint(scale, zeropoint);
}
virtual void unsetAttached() override
{
cropLayer->unsetAttached();
}
virtual bool getMemoryShapes(const std::vector<cv::dnn::MatShape>& inputs,
const int requiredOutputs,
std::vector<cv::dnn::MatShape>& outputs,
std::vector<cv::dnn::MatShape>& internals) const override
{
CV_Assert(inputs.size() == 1);
const auto& srcShape = inputs[0];
std::vector<int> outShape(srcShape.size());
for (int i = 0; i < srcShape.size(); i++)
{
outShape[i] = inputs[0][i] - cropSize[i] * 2;
}
outputs.assign(1, outShape);
return false;
//return cropLayer->getMemoryShapes(inputs, requiredOutputs, outputs, internals);
}
virtual bool updateMemoryShapes(const std::vector<cv::dnn::MatShape>& inputs) override
{
return cropLayer->updateMemoryShapes(inputs);
}
};
void reg();
int main(int argc, char** argv) {
//CV_DNN_REGISTER_LAYER_CLASS(CropCenter, CropCenterLayer);
reg();
// ImageNet CaffeƒŠƒtƒ@ƒŒƒ“ƒXƒƒfƒ
string protoFile = "models/upresnet10/noise0_scale2.0x_model.prototxt";
string modelFile = "models/upresnet10/noise0_scale2.0x_model.json.caffemodel";
// ‰æœƒtƒ@ƒCƒ
string imageFile = (argc > 1) ? argv[1] : "images/cat.jpg";
// CaffeƒƒfƒÌ“ÇÝ<E2809A>žÝ
cv::dnn::Net net;
try {
net = cv::dnn::readNetFromCaffe(protoFile, modelFile);
//net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
//net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
net.setPreferableBackend(cv::dnn::DNN_BACKEND_OPENCV);
net.setPreferableTarget(cv::dnn::DNN_TARGET_CPU);
}
catch (const cv::Exception& e) {
cerr << e.msg << endl;
exit(-1);
}
// ƒeƒXƒg—pÌ“ü—͉會tƒ@ƒCƒÌ“ÇÝ<E2809A>žÝ
cv::Mat img = cv::imread(imageFile);
if (img.empty()) {
cerr << "can't read image: " << imageFile << endl;
exit(-1);
}
try {
// “ü—͉æœðƒŠƒTƒCƒY
int cropSize = 90;
cv::resize(img, img, cv::Size(cropSize, cropSize));
// Caffeňµ¤BlobŒ`Ž®‚ɕϊ· (ŽÀÌÍcv::Mat̃‰ƒbƒp<C692>[ƒNƒ‰ƒX)
const auto inputBlob = cv::dnn::blobFromImage(img, 1.0 / 255.0, cv::Size(), cv::Scalar(), true, false, CV_32F);
std::vector<int> indim(inputBlob.size.p, inputBlob.size.p + inputBlob.size.dims());
// “ü—Íwɉæœð“ü—Í
net.setInput(inputBlob);
// ƒtƒHƒ<48><C692>[ƒhƒpƒX(<28>‡“`”d)ÌŒvŽZ&<26>o—Íw(Softmax)Ì<E2809A>o—ÍðŽæ“¾, ‚±‚±‚É—\ªŒ‰ÊªŠi”[‚³‚ê‚Ä‚¢‚é
// ImageNet 1000ƒNƒ‰ƒXˆÌŠm—¦(32bits•“®<E2809C>¬<EFBFBD>”“_l)ªŠi”[³ê½1x1000Ì<E2809A>s—ñ(ƒxƒNƒgƒ)
const auto probMat = net.forward();
std::vector<cv::Mat> outImgs;
cv::dnn::imagesFromBlob(probMat, outImgs);
//cv::dnn::imagesFromBlob(inputBlob, outImgs);
auto outImg = outImgs[0];
// lð0<C3B0>`1ɃNƒŠƒbƒsƒ“ƒO
cv::threshold(outImg, outImg, 1.0, 1.0, cv::THRESH_TRUNC);
cv::threshold(outImg, outImg, 0.0, 0.0, cv::THRESH_TOZERO);
const double clip_eps8 = (1.0 / 255.0) * 0.5 - (1.0e-7 * (1.0 / 255.0) * 0.5);
outImg.convertTo(outImg, CV_8U, 255.0, clip_eps8);
std::vector<int> outdim(outImg.size.p, outImg.size.p + outImg.size.dims());
cv::cvtColor(outImg, outImg, cv::COLOR_RGB2BGR);
cv::imwrite("test.png", outImg);
//// Šm—¦(<28>M—Š“x)Ì<E2809A>¢<E2809A>Ƀ\<5C>[ƒgµÄ<E2809A>A<EFBFBD>ãˆÊ5ẪCƒ“ƒfƒbƒNƒXðŽæ“¾
//cv::Mat sorted(probMat.rows, probMat.cols, CV_32F);
//cv::sortIdx(probMat, sorted, cv::SORT_EVERY_ROW | cv::SORT_DESCENDING);
//cv::Mat topk = sorted(cv::Rect(0, 0, 5, 1));
//// ƒJƒeƒSƒŠ¼ÌƒŠƒXƒgƒtƒ@ƒCƒ(synset_words.txt)ð“ÇÝ<E2809A>žÝ
//// ƒf<C692>[ƒ^—á: categoryList[951] = "lemon";
//vector<string> categoryList;
//string category;
//ifstream fs("synset_words.txt");
//if (!fs.is_open()) {
// cerr << "can't read file" << endl;
// exit(-1);
//}
//while (getline(fs, category)) {
// if (category.length()) {
// categoryList.push_back(category.substr(category.find(' ') + 1));
// }
//}
//fs.close();
//// —\ªµ½ƒJƒeƒSƒŠÆŠm—¦(<28>M—Š“x)ð<E2809A>o—Í
//cv::Mat_<int>::const_iterator it = topk.begin<int>();
//while (it != topk.end<int>()) {
// cout << categoryList[*it] << " : " << probMat.at<float>(*it) * 100 << " %" << endl;
// ++it;
//}
}
catch (const cv::Exception& e) {
cerr << e.msg << endl;
}
return 0;
}