|
| 1 | +#include "opencv_bridge.h" |
| 2 | + |
| 3 | +#include <string.h> |
| 4 | + |
| 5 | +MatVec3b MatVec3b_New() { |
| 6 | + return new cv::Mat_<cv::Vec3b>(); |
| 7 | +} |
| 8 | + |
| 9 | +struct ByteArray MatVec3b_ToJpegData(MatVec3b m, int quality){ |
| 10 | + std::vector<int> param(2); |
| 11 | + param[0] = CV_IMWRITE_JPEG_QUALITY; |
| 12 | + param[1] = quality; |
| 13 | + std::vector<uchar> data; |
| 14 | + cv::imencode(".jpg", *m, data, param); |
| 15 | + return toByteArray(reinterpret_cast<const char*>(&data[0]), data.size()); |
| 16 | +} |
| 17 | + |
| 18 | +void MatVec3b_Delete(MatVec3b m) { |
| 19 | + delete m; |
| 20 | +} |
| 21 | + |
| 22 | +void MatVec3b_CopyTo(MatVec3b src, MatVec3b dst) { |
| 23 | + src->copyTo(*dst); |
| 24 | +} |
| 25 | + |
| 26 | +int MatVec3b_Empty(MatVec3b m) { |
| 27 | + return m->empty(); |
| 28 | +} |
| 29 | + |
| 30 | +struct RawData MatVec3b_ToRawData(MatVec3b m) { |
| 31 | + int width = m->cols; |
| 32 | + int height = m->rows; |
| 33 | + int size = width * height * 3; |
| 34 | + char* data = reinterpret_cast<char*>(m->data); |
| 35 | + ByteArray byteData = {data, size}; |
| 36 | + RawData raw = {width, height, byteData}; |
| 37 | + return raw; |
| 38 | +} |
| 39 | + |
| 40 | +MatVec3b RawData_ToMatVec3b(struct RawData r) { |
| 41 | + int rows = r.height; |
| 42 | + int cols = r.width; |
| 43 | + cv::Mat_<cv::Vec3b>* mat = new cv::Mat_<cv::Vec3b>(rows, cols); |
| 44 | + unsigned char* data = reinterpret_cast<unsigned char*>(r.data.data); |
| 45 | + mat->data = data; |
| 46 | + return mat; |
| 47 | +} |
| 48 | + |
| 49 | +void MatVec4b_Delete(MatVec4b m) { |
| 50 | + delete m; |
| 51 | +} |
| 52 | + |
| 53 | +struct RawData MatVec4b_ToRawData(MatVec4b m) { |
| 54 | + int width = m->cols; |
| 55 | + int height = m->rows; |
| 56 | + int size = width * height * 4; |
| 57 | + char* data = reinterpret_cast<char*>(m->data); |
| 58 | + ByteArray byteData = {data, size}; |
| 59 | + RawData raw = {width, height, byteData}; |
| 60 | + return raw; |
| 61 | +} |
| 62 | + |
| 63 | +MatVec4b RawData_ToMatVec4b(struct RawData r) { |
| 64 | + int rows = r.height; |
| 65 | + int cols = r.width; |
| 66 | + cv::Mat_<cv::Vec4b>* mat = new cv::Mat_<cv::Vec4b>(rows, cols); |
| 67 | + unsigned char* data = reinterpret_cast<unsigned char*>(r.data.data); |
| 68 | + mat->data = data; |
| 69 | + return mat; |
| 70 | +} |
| 71 | + |
| 72 | +VideoCapture VideoCapture_New() { |
| 73 | + return new cv::VideoCapture(); |
| 74 | +} |
| 75 | + |
| 76 | +void VideoCapture_Delete(VideoCapture v) { |
| 77 | + delete v; |
| 78 | +} |
| 79 | + |
| 80 | +int VideoCapture_Open(VideoCapture v, const char* uri) { |
| 81 | + return v->open(uri); |
| 82 | +} |
| 83 | + |
| 84 | +int VideoCapture_OpenDevice(VideoCapture v, int device) { |
| 85 | + return v->open(device); |
| 86 | +} |
| 87 | + |
| 88 | +void VideoCapture_Release(VideoCapture v) { |
| 89 | + v->release(); |
| 90 | +} |
| 91 | + |
| 92 | +void VideoCapture_Set(VideoCapture v, int prop, int param) { |
| 93 | + v->set(prop, param); |
| 94 | +} |
| 95 | + |
| 96 | +int VideoCapture_IsOpened(VideoCapture v) { |
| 97 | + return v->isOpened(); |
| 98 | +} |
| 99 | + |
| 100 | +int VideoCapture_Read(VideoCapture v, MatVec3b buf) { |
| 101 | + return v->read(*buf); |
| 102 | +} |
| 103 | + |
| 104 | +void VideoCapture_Grab(VideoCapture v, int skip) { |
| 105 | + for (int i =0; i < skip; i++) { |
| 106 | + v->grab(); |
| 107 | + } |
| 108 | +} |
| 109 | + |
| 110 | +VideoWriter VideoWriter_New() { |
| 111 | + return new cv::VideoWriter(); |
| 112 | +} |
| 113 | + |
| 114 | +void VideoWriter_Delete(VideoWriter vw) { |
| 115 | + delete vw; |
| 116 | +} |
| 117 | + |
| 118 | +void VideoWriter_Open(VideoWriter vw, const char* name, double fps, int width, |
| 119 | + int height) { |
| 120 | + vw->open(name, CV_FOURCC('M', 'J', 'P', 'G'), fps, cv::Size(width, height), true); |
| 121 | +} |
| 122 | + |
| 123 | +void VideoWriter_OpenWithMat(VideoWriter vw, const char* name, double fps, |
| 124 | + MatVec3b img) { |
| 125 | + vw->open(name, CV_FOURCC('M', 'J', 'P', 'G'), fps, img->size(), true); |
| 126 | +} |
| 127 | + |
| 128 | +int VideoWriter_IsOpened(VideoWriter vw) { |
| 129 | + return vw->isOpened(); |
| 130 | +} |
| 131 | + |
| 132 | +void VideoWriter_Write(VideoWriter vw, MatVec3b img) { |
| 133 | + *vw << *img; |
| 134 | +} |
| 135 | + |
| 136 | +CascadeClassifier CascadeClassifier_New() { |
| 137 | + return new cv::CascadeClassifier(); |
| 138 | +} |
| 139 | + |
| 140 | +void CascadeClassifier_Delete(CascadeClassifier cs) { |
| 141 | + delete cs; |
| 142 | +} |
| 143 | + |
| 144 | +int CascadeClassifier_Load(CascadeClassifier cs, const char* name) { |
| 145 | + return cs->load(name); |
| 146 | +} |
| 147 | + |
| 148 | +struct Rects CascadeClassifier_DetectMultiScale(CascadeClassifier cs, MatVec3b img) { |
| 149 | + std::vector<cv::Rect> faces; |
| 150 | + cs->detectMultiScale(*img, faces); // TODO control default parameter |
| 151 | + Rect* rects = new Rect[faces.size()]; |
| 152 | + for (size_t i = 0; i < faces.size(); ++i) { |
| 153 | + Rect r = {faces[i].x, faces[i].y, faces[i].width, faces[i].height}; |
| 154 | + rects[i] = r; |
| 155 | + } |
| 156 | + Rects ret = {rects, (int)faces.size()}; |
| 157 | + return ret; |
| 158 | +} |
| 159 | + |
| 160 | +void Rects_Delete(struct Rects rs) { |
| 161 | + delete rs.rects; |
| 162 | +} |
| 163 | + |
| 164 | +void DrawRectsToImage(MatVec3b img, struct Rects rects) { |
| 165 | + for (int i = 0; i < rects.length; ++i) { |
| 166 | + Rect r = rects.rects[i]; |
| 167 | + cv::rectangle(*img, cv::Point(r.x, r.y), cv::Point(r.x+r.width, r.y+r.height), |
| 168 | + cv::Scalar(0, 200, 0), 3, CV_AA); |
| 169 | + } |
| 170 | +} |
| 171 | + |
| 172 | +MatVec4b LoadAlphaImg(const char* name) { |
| 173 | + cv::Mat_<cv::Vec4b> img = cv::imread(name, cv::IMREAD_UNCHANGED); |
| 174 | + return new cv::Mat_<cv::Vec4b>(img); |
| 175 | +} |
| 176 | + |
| 177 | +void MountAlphaImage(MatVec4b img, MatVec3b back, struct Rects rects) { |
| 178 | + cv::Mat_<cv::Vec4b> resized; |
| 179 | + for (int i = 0; i < rects.length; ++i) { |
| 180 | + Rect r = rects.rects[i]; |
| 181 | + int col, row; |
| 182 | + if (r.width < r.height) { |
| 183 | + col = img->cols * r.height / img->rows; |
| 184 | + row = r.height; |
| 185 | + } else { |
| 186 | + col = r.width; |
| 187 | + row = img->rows * r.width / img->cols; |
| 188 | + } |
| 189 | + int ltx = r.x + r.width * 0.5 - col * 0.5; |
| 190 | + int lty = r.y + r.height * 0.5 - row * 0.5; |
| 191 | + std::vector<cv::Point2f> tgtPt; |
| 192 | + tgtPt.push_back(cv::Point2f(ltx, lty)); |
| 193 | + tgtPt.push_back(cv::Point2f(ltx+col, lty)); |
| 194 | + tgtPt.push_back(cv::Point2f(ltx+col, lty+row)); |
| 195 | + tgtPt.push_back(cv::Point2f(ltx, lty+row)); |
| 196 | + |
| 197 | + cv::Mat img_rgb, img_aaa, img_backa; |
| 198 | + std::vector<cv::Mat> planes_rgba, planes_rgb, planes_aaa, planes_backa; |
| 199 | + int maxVal = pow(2, 8 * back->elemSize1()) - 1; |
| 200 | + |
| 201 | + std::vector<cv::Point2f> srcPt; |
| 202 | + srcPt.push_back(cv::Point2f(0, 0)); |
| 203 | + srcPt.push_back(cv::Point2f(img->cols-1, 0)); |
| 204 | + srcPt.push_back(cv::Point2f(img->cols-1, img->rows-1)); |
| 205 | + srcPt.push_back(cv::Point2f(0, img->rows-1)); |
| 206 | + cv::Mat mat = cv::getPerspectiveTransform(srcPt, tgtPt); |
| 207 | + |
| 208 | + cv::Mat alpha0(back->rows, back->cols, img->type()); |
| 209 | + alpha0 = cv::Scalar::all(0); |
| 210 | + cv::warpPerspective(*img, alpha0, mat, alpha0.size(), cv::INTER_CUBIC, |
| 211 | + cv::BORDER_TRANSPARENT); |
| 212 | + |
| 213 | + cv::split(alpha0, planes_rgba); |
| 214 | + |
| 215 | + planes_rgb.push_back(planes_rgba[0]); |
| 216 | + planes_rgb.push_back(planes_rgba[1]); |
| 217 | + planes_rgb.push_back(planes_rgba[2]); |
| 218 | + merge(planes_rgb, img_rgb); |
| 219 | + |
| 220 | + planes_aaa.push_back(planes_rgba[3]); |
| 221 | + planes_aaa.push_back(planes_rgba[3]); |
| 222 | + planes_aaa.push_back(planes_rgba[3]); |
| 223 | + merge(planes_aaa, img_aaa); |
| 224 | + |
| 225 | + planes_backa.push_back(maxVal - planes_rgba[3]); |
| 226 | + planes_backa.push_back(maxVal - planes_rgba[3]); |
| 227 | + planes_backa.push_back(maxVal - planes_rgba[3]); |
| 228 | + merge(planes_backa, img_backa); |
| 229 | + |
| 230 | + *back = img_rgb.mul(img_aaa, 1.0/(float)maxVal) |
| 231 | + + back->mul(img_backa, 1.0/(float)maxVal); |
| 232 | + } |
| 233 | +} |
0 commit comments