Advertisement
Guest User

Untitled

a guest
Jan 18th, 2017
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.72 KB | None | 0 0
  1. // Copyright 2013
  2. // Author: David Tsai (caihsiaoster@gmail.com)
  3. // Stephen Holiday (stephen.holiday@gmail.com)
  4. #include <glog/logging.h>
  5. #include <math.h>
  6. #include <opencv2/core/core_c.h>
  7. #include <opencv2/highgui/highgui.hpp>
  8. #include <opencv2/highgui/highgui_c.h>
  9. #include <opencv2/imgproc/imgproc.hpp>
  10. #include <openssl/md5.h>
  11. #include <stdio.h>
  12. #include <ostream>
  13. #include "boost/regex.hpp"
  14.  
  15. #include "common/fileutil/file.h"
  16. #include "common/opencvutil/opencvutil.h"
  17. #include "common/s3util.h"
  18. #include "common/webutil/webutil.h"
  19. #include "vision/detector/proto/detector.pb.h"
  20.  
  21. using webutil::IsUrl;
  22. using webutil::FetchUrlToString;
  23.  
  24. using cv::Rect;
  25.  
  26. namespace opencvutil {
  27.  
  28.  
  29. void ComputeMD5(const string& contents, string* md5) {
  30. unsigned char digest[MD5_DIGEST_LENGTH]; // default is 16
  31. MD5((const unsigned char*)contents.c_str(), contents.length(), digest);
  32. char signature[MD5_DIGEST_LENGTH * 2 + 1];
  33. for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
  34. sprintf(&signature[i*2], "%02x", (unsigned int)digest[i]);
  35. }
  36. *md5 = string(signature);
  37. }
  38.  
  39.  
  40. bool LoadImageFromUrlMD5(const string& url,
  41. const bool is_color,
  42. Mat* image,
  43. string* md5,
  44. long timeout_ms) {
  45. if (IsUrl(url)) {
  46. string raw_image;
  47. if (!(FetchUrlToString(url, &raw_image, timeout_ms))) {
  48. VLOG(0) << " Cannot fetch image";
  49. return false;
  50. }
  51. if (raw_image.size() <= 0) {
  52. LOG(ERROR) << "The url content was empty.";
  53. return false;
  54. }
  55. if (md5) {
  56. ComputeMD5(raw_image, md5);
  57. }
  58. std::vector<char> raw_image_vec (raw_image.begin(), raw_image.end());
  59. if (is_color) {
  60. *image = cv::imdecode(raw_image_vec, CV_LOAD_IMAGE_COLOR);
  61. } else {
  62. *image = cv::imdecode(raw_image_vec, CV_LOAD_IMAGE_GRAYSCALE);
  63. }
  64. // if (!DecodeRawStringToImage(raw_image, is_color, image)) {
  65. // LOG(ERROR) << "Failed to fetch image from " << url;
  66. // return false;
  67. // }
  68. } else {
  69. if (is_color) {
  70. *image = cv::imread(url, CV_LOAD_IMAGE_COLOR);
  71. } else {
  72. *image = cv::imread(url, CV_LOAD_IMAGE_GRAYSCALE);
  73. }
  74. if (!image->empty()) {
  75. string raw_image;
  76. google::protobuf::File::ReadFileToStringOrDie(url, &raw_image);
  77. ComputeMD5(raw_image, md5);
  78. }
  79. }
  80. if (image->data) {
  81. return true;
  82. } else {
  83. LOG(ERROR) << "Failed loading image from " << url << "!";
  84. return false;
  85. }
  86. }
  87.  
  88. bool FetchImageFromS3(const string& url, string* dest) {
  89. // if this url is a s3 path
  90. // Full path: "s3://pinlogs/vision/camera_user_data/dt=2017-01-15/12345"
  91. // s3 bucket: "pinlogs"
  92. // s3 key: "vision/camera_user_data/dt=2017-01-15/12345"
  93. static boost::regex s3_path("^s3://([^/]+)/(.*?([^/]+)/?)$");
  94. boost::cmatch matching;
  95. if (!boost::regex_match(url.c_str(), matching, s3_path)) {
  96. LOG(ERROR) << "Error when parsing s3 path.";
  97. return false;
  98. }
  99. if (matching.size() <= 3) {
  100. LOG(ERROR) << "S3 path doesn't have the correct pattern";
  101. return false;
  102. }
  103. string s3_bucket(matching[1]), s3_key(matching[2]);
  104. // TODO(@zhefei): figure out a correct rate limiting
  105. auto s3Util = common::S3Util::BuildS3Util(50, s3_bucket);
  106. auto responses = s3Util->sdkGetObject(s3_key, "");
  107. if (!responses.IsSuccess()) {
  108. LOG(ERROR) << "Error when fetching image from s3: "
  109. << responses.GetError().GetMessage();
  110. return false;
  111. }
  112. std::ostringstream ss;
  113. ss << responses.GetResult().GetBody().rdbuf();
  114. *dest = ss.str();
  115. return true;
  116.  
  117. }
  118.  
  119. bool LoadImageFromUrl(const string& url,
  120. const bool is_color,
  121. Mat* image,
  122. long timeout_ms) {
  123. if (IsUrl(url) or (url.length() > 5 && url.substr(0, 5) == "s3://")) {
  124. string raw_image;
  125.  
  126. if (IsUrl(url)) {
  127. if (!(FetchUrlToString(url, &raw_image, timeout_ms))) {
  128. return false;
  129. }
  130. } else {
  131. if (!FetchImageFromS3(url, &raw_image)) {
  132. return false;
  133. }
  134. }
  135.  
  136. if (raw_image.size() <= 0) {
  137. LOG(ERROR) << "The url content was empty.";
  138. return false;
  139. }
  140. std::vector<char> raw_image_vec (raw_image.begin(), raw_image.end());
  141. if (is_color) {
  142. *image = cv::imdecode(raw_image_vec, CV_LOAD_IMAGE_COLOR);
  143. } else {
  144. *image = cv::imdecode(raw_image_vec, CV_LOAD_IMAGE_GRAYSCALE);
  145. }
  146. // if (!DecodeRawStringToImage(raw_image, is_color, image)) {
  147. // LOG(ERROR) << "Failed to fetch image from " << url;
  148. // return false;
  149. // }
  150. } else {
  151. if (is_color) {
  152. *image = cv::imread(url, CV_LOAD_IMAGE_COLOR);
  153. } else {
  154. *image = cv::imread(url, CV_LOAD_IMAGE_GRAYSCALE);
  155. }
  156. }
  157. if (image->data) {
  158. return true;
  159. } else {
  160. VLOG(1) << "Failed loading image from " << url << "!";
  161. return false;
  162. }
  163. }
  164.  
  165.  
  166. bool DecodeRawStringToImage(const string& raw_image,
  167. const bool is_color,
  168. Mat* image) {
  169. CvMat m;
  170. cvInitMatHeader(&m, 1, raw_image.size(),
  171. CV_8U, (void*)(raw_image.c_str()));
  172. if (is_color) {
  173. *image = cvDecodeImage(&m);
  174. } else {
  175. *image = cvDecodeImage(&m, CV_LOAD_IMAGE_GRAYSCALE);
  176. }
  177.  
  178. if (image->empty()) {
  179. return false;
  180. } else {
  181. return true;
  182. }
  183. }
  184.  
  185. // Rotation around the center
  186. void Rotate(const cv::Mat& src, double angle, cv::Mat& dst) {
  187. cv::Point2f pt(src.cols/2., src.rows/2.);
  188. cv::Mat r = cv::getRotationMatrix2D(pt, angle, 1.0);
  189. cv::warpAffine(src, dst, r, cv::Size(src.cols, src.rows));
  190. }
  191.  
  192.  
  193. float ScaleImageUsingArea(const Mat& original,
  194. const int area,
  195. Mat* dest) {
  196. return ScaleImageUsingArea(original, area, true, dest);
  197. }
  198.  
  199. float ScaleImageUsingArea(const Mat& original,
  200. const int area,
  201. const bool small_only,
  202. Mat* dest) {
  203. int width = original.cols;
  204. int height = original.rows;
  205.  
  206. if (small_only) {
  207. if (width * height < area) {
  208. *dest = original;
  209. return 1.0f;
  210. }
  211. }
  212.  
  213. float percent = sqrt((float)area / (float)(width * height));
  214. cv::Mat resize_image;
  215. cv::resize(original, *dest,
  216. cvSize((int) (width * percent),(int) (height * percent)),
  217. 0, 0, cv::INTER_LINEAR);
  218.  
  219. return percent;
  220. }
  221.  
  222.  
  223. bool ScaleImageUsingShortEdge(const Mat& original,
  224. const int short_dim,
  225. Mat* dest) {
  226. if (&original == dest) {
  227. LOG(ERROR) << "Original and destination images must be different!";
  228. return false;
  229. }
  230.  
  231. int width = original.cols;
  232. int height = original.rows;
  233. int short_edge = width < height ? width : height;
  234.  
  235. float percent = 1.0f;
  236. if (short_edge > short_dim) {
  237. percent = static_cast<float>(short_dim) / short_edge;
  238. }
  239.  
  240. // LOG(INFO) << "Resize ratio: " << percent;
  241.  
  242. resize(original, *dest,
  243. cvSize((int)(width * percent), (int)(height*percent)), 0, 0, cv::INTER_LINEAR);
  244.  
  245. return true;
  246. }
  247.  
  248.  
  249.  
  250. bool DrawBoundingBoxes(const BoxedImage& bi, Mat* img) {
  251. if (!img) {
  252. return false;
  253. }
  254. int num = bi.boxes_size();
  255. for (int i = 0; i < num; ++i) {
  256. const BoundingBox& bb = bi.boxes(i);
  257. // Generate a random color for drawing the bounding box.
  258. int thickness = 3;
  259. cv::rectangle(*img,
  260. cv::Point(bb.x1(), bb.y1()),
  261. cv::Point((bb.x2()), (bb.y2())),
  262. GetRandomColor(i), thickness);
  263. }
  264. return true;
  265. }
  266.  
  267.  
  268.  
  269.  
  270.  
  271. cv::Scalar GetRandomColor(int i) {
  272. std::vector<cv::Scalar> c;
  273. c.push_back(cv::Scalar(255, 97, 0));
  274. c.push_back(cv::Scalar(65, 105, 225));
  275. c.push_back(cv::Scalar(0, 255, 255));
  276. c.push_back(cv::Scalar(0, 255, 0));
  277. c.push_back(cv::Scalar(255, 0, 0));
  278. c.push_back(cv::Scalar(0, 0, 255));
  279. c.push_back(cv::Scalar(255, 0, 255));
  280. c.push_back(cv::Scalar(218, 112, 214));
  281. c.push_back(cv::Scalar(30, 144, 255));
  282. c.push_back(cv::Scalar(244, 124, 96));
  283. int color = i % c.size();
  284. return c[color];
  285. }
  286.  
  287. } // namespace opencvutil
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement