1 /* 2 Copyright (c) 2019 Ferhat Kurtulmuş 3 Boost Software License - Version 1.0 - August 17th, 2003 4 Permission is hereby granted, free of charge, to any person or organization 5 obtaining a copy of the software and accompanying documentation covered by 6 this license (the "Software") to use, reproduce, display, distribute, 7 execute, and transmit the Software, and to prepare derivative works of the 8 Software, and to permit third-parties to whom the Software is furnished to 9 do so, all subject to the following: 10 The copyright notices in the Software and this entire statement, including 11 the above license grant, this restriction and the following disclaimer, 12 must be included in all copies of the Software, in whole or in part, and 13 all derivative works of the Software, unless such copies or derivative 14 works are solely in the form of machine-executable object code generated by 15 a source language processor. 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 19 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 20 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 DEALINGS IN THE SOFTWARE. 23 */ 24 25 module opencvd.dnn; 26 27 import core.stdc.stdlib; 28 import core.stdc.stdint; 29 import std.conv; 30 import std.typecons; 31 import std..string; 32 33 import opencvd.cvcore; 34 35 private extern (C) { 36 Net Net_ReadNet(const char* model, const char* config); 37 Net Net_ReadNetBytes(const char* framework, ByteArray model, ByteArray config); 38 Net Net_ReadNetFromCaffe(const char* prototxt, const char* caffeModel); 39 Net Net_ReadNetFromCaffeBytes(ByteArray prototxt, ByteArray caffeModel); 40 Net Net_ReadNetFromTensorflow(const char* model); 41 Net Net_ReadNetFromTensorflowBytes(ByteArray model); 42 Mat Net_BlobFromImage(Mat image, double scalefactor, Size size, Scalar mean, bool swapRB, 43 bool crop); 44 IntVector DNN_NMSBoxes(RotatedRects rects, FloatVector scores, float score_threshold, float nms_threshold, float eta, int top_k); 45 void Net_Close(Net net); 46 bool Net_Empty(Net net); 47 void Net_SetInput(Net net, Mat blob, const char* name); 48 Mat Net_Forward(Net net, const char* outputName); 49 void Net_ForwardLayers(Net net, Mats* outputBlobs, CStrings outBlobNames); 50 void Net_SetPreferableBackend(Net net, int backend); 51 void Net_SetPreferableTarget(Net net, int target); 52 int64_t Net_GetPerfProfile(Net net); 53 void Net_GetUnconnectedOutLayers(Net net, IntVector* res); 54 55 Mat Net_GetBlobChannel(Mat blob, int imgidx, int chnidx); 56 Scalar Net_GetBlobSize(Mat blob); 57 58 Layer Net_GetLayer(Net net, int layerid); 59 void Layer_Close(Layer layer); 60 int Layer_InputNameToIndex(Layer layer, const char* name); 61 int Layer_OutputNameToIndex(Layer layer, const char* name); 62 const(char*) Layer_GetName(Layer layer); 63 const(char*) Layer_GetType(Layer layer); 64 } 65 66 enum: int { 67 DNN_BACKEND_DEFAULT, 68 DNN_BACKEND_HALIDE, 69 DNN_BACKEND_INFERENCE_ENGINE, 70 DNN_BACKEND_OPENCV, 71 DNN_BACKEND_VKCOM, 72 } 73 74 enum: int { 75 DNN_TARGET_CPU, 76 DNN_TARGET_OPENCL, 77 DNN_TARGET_OPENCL_FP16, 78 DNN_TARGET_MYRIAD, 79 DNN_TARGET_VULKAN, 80 DNN_TARGET_FPGA 81 } 82 83 struct Net { 84 void* p; 85 86 bool empty(){ 87 return Net_Empty(this) == 0 ? false: true; 88 } 89 90 void setInput(Mat blob, string name = ""){ 91 Net_SetInput(this, blob, name.toStringz); 92 } 93 94 Mat forward(string outputName = ""){ 95 Mat _net = Net_Forward(this, outputName.toStringz); 96 return _net; 97 } 98 99 void forward(ref Mat[] outputBlobs, string[] outBlobNames){ 100 import core.stdc.stdlib; 101 char** cstrs = cast(char**)malloc(outBlobNames.length * (char*).sizeof); 102 for(int i = 0; i < outBlobNames.length; i++){ 103 cstrs[i] = cast(char*)outBlobNames[i].toStringz; 104 105 } 106 107 CStrings coutBlobNames = {cstrs, outBlobNames.length.to!int}; 108 Mats obs; 109 Net_ForwardLayers(this, &obs, coutBlobNames); 110 free(cstrs); 111 outputBlobs = obs.mats[0..obs.length].dup; 112 Mats_Close(obs); 113 } 114 115 void setPreferableBackend(int backend){ 116 Net_SetPreferableBackend(this, backend); 117 } 118 119 void setPreferableTarget(int target){ 120 Net_SetPreferableTarget(this, target); 121 } 122 123 int64_t getPerfProfile(){ 124 return Net_GetPerfProfile(this); 125 } 126 127 void getUnconnectedOutLayers(ref int[] res){ 128 IntVector *_res; 129 Net_GetUnconnectedOutLayers(this, _res); 130 131 res = _res.val[0.._res.length].dup; 132 Close_IntVector(*_res); 133 } 134 135 Layer getLayer(int layerid){ 136 return Net_GetLayer(this, layerid); 137 } 138 } 139 140 Mat getBlobChannel(Mat blob, int imgidx, int chnidx){ 141 return Net_GetBlobChannel(blob, imgidx, chnidx); 142 } 143 144 Scalar getBlobSize(Mat blob){ 145 return Net_GetBlobSize(blob); 146 } 147 148 void Destroy(Net net){ 149 Net_Close(net); 150 } 151 152 Net readNet(string model, string config = ""){ 153 return Net_ReadNet(toStringz(model), toStringz(config)); 154 } 155 156 Net readNetBytes(string framework, ubyte[] model, ubyte[] config){ 157 return Net_ReadNetBytes(framework.toStringz, ByteArray(model.ptr, model.length.to!int), ByteArray(config.ptr, config.length.to!int)); 158 } 159 160 Net readNetFromCaffe(string prototxt, string caffeModel){ 161 return Net_ReadNetFromCaffe(prototxt.toStringz, caffeModel.toStringz); 162 } 163 164 Net readNetFromCaffeBytes(ubyte[] prototxt, ubyte[] caffeModel){ 165 return Net_ReadNetFromCaffeBytes(ByteArray(prototxt.ptr, prototxt.length.to!int), 166 ByteArray(caffeModel.ptr, caffeModel.length.to!int)); 167 } 168 169 Net readNetFromTensorflow(string model){ 170 return Net_ReadNetFromTensorflow(model.toStringz); 171 } 172 173 Net readNetFromTensorflowBytes(ubyte[] model){ 174 return Net_ReadNetFromTensorflowBytes(ByteArray(model.ptr, model.length.to!int)); 175 } 176 177 Mat blobFromImage(Mat image, double scalefactor=1.0, Size size = Size(), Scalar mean = Scalar(), bool swapRB = false, bool crop = false){ 178 return Net_BlobFromImage(image, scalefactor, size, mean, swapRB, crop); 179 } 180 181 int[] NMSBoxes(RotatedRect[] rects, float[] scores, float score_threshold, float nms_threshold, float eta = 1.0f, int top_k = 0){ 182 IntVector _indices = DNN_NMSBoxes(RotatedRects(rects.ptr, rects.length.to!int), 183 FloatVector(scores.ptr, scores.length.to!int), score_threshold, nms_threshold, eta, top_k); 184 185 int[] indices = _indices.val[0.._indices.length].dup; 186 Close_IntVector(_indices); 187 188 return indices; 189 } 190 191 struct Layer { 192 void* p; 193 194 int inputNameToIndex(string name){ 195 return Layer_InputNameToIndex(this, name.toStringz); 196 } 197 198 int outputNameToIndex(string name){ 199 return Layer_OutputNameToIndex(this, name.toStringz); 200 } 201 202 string getName(){ 203 return Layer_GetName(this).to!string; 204 } 205 206 string getType(){ 207 return Layer_GetType(this).to!string; 208 } 209 210 } 211 212 void Destroy(Layer layer){ 213 Layer_Close(layer); 214 }