mirror of
https://github.com/lltcggie/waifu2x-caffe.git
synced 2025-11-24 10:34:54 +00:00
379 lines
12 KiB
C++
379 lines
12 KiB
C++
# 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;
|
||
}
|