Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Copyright 2013
- // Author: David Tsai (caihsiaoster@gmail.com)
- // Stephen Holiday (stephen.holiday@gmail.com)
- #include <glog/logging.h>
- #include <math.h>
- #include <opencv2/core/core_c.h>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2/highgui/highgui_c.h>
- #include <opencv2/imgproc/imgproc.hpp>
- #include <openssl/md5.h>
- #include <stdio.h>
- #include <ostream>
- #include "boost/regex.hpp"
- #include "common/fileutil/file.h"
- #include "common/opencvutil/opencvutil.h"
- #include "common/s3util.h"
- #include "common/webutil/webutil.h"
- #include "vision/detector/proto/detector.pb.h"
- using webutil::IsUrl;
- using webutil::FetchUrlToString;
- using cv::Rect;
- namespace opencvutil {
- void ComputeMD5(const string& contents, string* md5) {
- unsigned char digest[MD5_DIGEST_LENGTH]; // default is 16
- MD5((const unsigned char*)contents.c_str(), contents.length(), digest);
- char signature[MD5_DIGEST_LENGTH * 2 + 1];
- for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
- sprintf(&signature[i*2], "%02x", (unsigned int)digest[i]);
- }
- *md5 = string(signature);
- }
- bool LoadImageFromUrlMD5(const string& url,
- const bool is_color,
- Mat* image,
- string* md5,
- long timeout_ms) {
- if (IsUrl(url)) {
- string raw_image;
- if (!(FetchUrlToString(url, &raw_image, timeout_ms))) {
- VLOG(0) << " Cannot fetch image";
- return false;
- }
- if (raw_image.size() <= 0) {
- LOG(ERROR) << "The url content was empty.";
- return false;
- }
- if (md5) {
- ComputeMD5(raw_image, md5);
- }
- std::vector<char> raw_image_vec (raw_image.begin(), raw_image.end());
- if (is_color) {
- *image = cv::imdecode(raw_image_vec, CV_LOAD_IMAGE_COLOR);
- } else {
- *image = cv::imdecode(raw_image_vec, CV_LOAD_IMAGE_GRAYSCALE);
- }
- // if (!DecodeRawStringToImage(raw_image, is_color, image)) {
- // LOG(ERROR) << "Failed to fetch image from " << url;
- // return false;
- // }
- } else {
- if (is_color) {
- *image = cv::imread(url, CV_LOAD_IMAGE_COLOR);
- } else {
- *image = cv::imread(url, CV_LOAD_IMAGE_GRAYSCALE);
- }
- if (!image->empty()) {
- string raw_image;
- google::protobuf::File::ReadFileToStringOrDie(url, &raw_image);
- ComputeMD5(raw_image, md5);
- }
- }
- if (image->data) {
- return true;
- } else {
- LOG(ERROR) << "Failed loading image from " << url << "!";
- return false;
- }
- }
- bool FetchImageFromS3(const string& url, string* dest) {
- // if this url is a s3 path
- // Full path: "s3://pinlogs/vision/camera_user_data/dt=2017-01-15/12345"
- // s3 bucket: "pinlogs"
- // s3 key: "vision/camera_user_data/dt=2017-01-15/12345"
- static boost::regex s3_path("^s3://([^/]+)/(.*?([^/]+)/?)$");
- boost::cmatch matching;
- if (!boost::regex_match(url.c_str(), matching, s3_path)) {
- LOG(ERROR) << "Error when parsing s3 path.";
- return false;
- }
- if (matching.size() <= 3) {
- LOG(ERROR) << "S3 path doesn't have the correct pattern";
- return false;
- }
- string s3_bucket(matching[1]), s3_key(matching[2]);
- // TODO(@zhefei): figure out a correct rate limiting
- auto s3Util = common::S3Util::BuildS3Util(50, s3_bucket);
- auto responses = s3Util->sdkGetObject(s3_key, "");
- if (!responses.IsSuccess()) {
- LOG(ERROR) << "Error when fetching image from s3: "
- << responses.GetError().GetMessage();
- return false;
- }
- std::ostringstream ss;
- ss << responses.GetResult().GetBody().rdbuf();
- *dest = ss.str();
- return true;
- }
- bool LoadImageFromUrl(const string& url,
- const bool is_color,
- Mat* image,
- long timeout_ms) {
- if (IsUrl(url) or (url.length() > 5 && url.substr(0, 5) == "s3://")) {
- string raw_image;
- if (IsUrl(url)) {
- if (!(FetchUrlToString(url, &raw_image, timeout_ms))) {
- return false;
- }
- } else {
- if (!FetchImageFromS3(url, &raw_image)) {
- return false;
- }
- }
- if (raw_image.size() <= 0) {
- LOG(ERROR) << "The url content was empty.";
- return false;
- }
- std::vector<char> raw_image_vec (raw_image.begin(), raw_image.end());
- if (is_color) {
- *image = cv::imdecode(raw_image_vec, CV_LOAD_IMAGE_COLOR);
- } else {
- *image = cv::imdecode(raw_image_vec, CV_LOAD_IMAGE_GRAYSCALE);
- }
- // if (!DecodeRawStringToImage(raw_image, is_color, image)) {
- // LOG(ERROR) << "Failed to fetch image from " << url;
- // return false;
- // }
- } else {
- if (is_color) {
- *image = cv::imread(url, CV_LOAD_IMAGE_COLOR);
- } else {
- *image = cv::imread(url, CV_LOAD_IMAGE_GRAYSCALE);
- }
- }
- if (image->data) {
- return true;
- } else {
- VLOG(1) << "Failed loading image from " << url << "!";
- return false;
- }
- }
- bool DecodeRawStringToImage(const string& raw_image,
- const bool is_color,
- Mat* image) {
- CvMat m;
- cvInitMatHeader(&m, 1, raw_image.size(),
- CV_8U, (void*)(raw_image.c_str()));
- if (is_color) {
- *image = cvDecodeImage(&m);
- } else {
- *image = cvDecodeImage(&m, CV_LOAD_IMAGE_GRAYSCALE);
- }
- if (image->empty()) {
- return false;
- } else {
- return true;
- }
- }
- // Rotation around the center
- void Rotate(const cv::Mat& src, double angle, cv::Mat& dst) {
- cv::Point2f pt(src.cols/2., src.rows/2.);
- cv::Mat r = cv::getRotationMatrix2D(pt, angle, 1.0);
- cv::warpAffine(src, dst, r, cv::Size(src.cols, src.rows));
- }
- float ScaleImageUsingArea(const Mat& original,
- const int area,
- Mat* dest) {
- return ScaleImageUsingArea(original, area, true, dest);
- }
- float ScaleImageUsingArea(const Mat& original,
- const int area,
- const bool small_only,
- Mat* dest) {
- int width = original.cols;
- int height = original.rows;
- if (small_only) {
- if (width * height < area) {
- *dest = original;
- return 1.0f;
- }
- }
- float percent = sqrt((float)area / (float)(width * height));
- cv::Mat resize_image;
- cv::resize(original, *dest,
- cvSize((int) (width * percent),(int) (height * percent)),
- 0, 0, cv::INTER_LINEAR);
- return percent;
- }
- bool ScaleImageUsingShortEdge(const Mat& original,
- const int short_dim,
- Mat* dest) {
- if (&original == dest) {
- LOG(ERROR) << "Original and destination images must be different!";
- return false;
- }
- int width = original.cols;
- int height = original.rows;
- int short_edge = width < height ? width : height;
- float percent = 1.0f;
- if (short_edge > short_dim) {
- percent = static_cast<float>(short_dim) / short_edge;
- }
- // LOG(INFO) << "Resize ratio: " << percent;
- resize(original, *dest,
- cvSize((int)(width * percent), (int)(height*percent)), 0, 0, cv::INTER_LINEAR);
- return true;
- }
- bool DrawBoundingBoxes(const BoxedImage& bi, Mat* img) {
- if (!img) {
- return false;
- }
- int num = bi.boxes_size();
- for (int i = 0; i < num; ++i) {
- const BoundingBox& bb = bi.boxes(i);
- // Generate a random color for drawing the bounding box.
- int thickness = 3;
- cv::rectangle(*img,
- cv::Point(bb.x1(), bb.y1()),
- cv::Point((bb.x2()), (bb.y2())),
- GetRandomColor(i), thickness);
- }
- return true;
- }
- cv::Scalar GetRandomColor(int i) {
- std::vector<cv::Scalar> c;
- c.push_back(cv::Scalar(255, 97, 0));
- c.push_back(cv::Scalar(65, 105, 225));
- c.push_back(cv::Scalar(0, 255, 255));
- c.push_back(cv::Scalar(0, 255, 0));
- c.push_back(cv::Scalar(255, 0, 0));
- c.push_back(cv::Scalar(0, 0, 255));
- c.push_back(cv::Scalar(255, 0, 255));
- c.push_back(cv::Scalar(218, 112, 214));
- c.push_back(cv::Scalar(30, 144, 255));
- c.push_back(cv::Scalar(244, 124, 96));
- int color = i % c.size();
- return c[color];
- }
- } // namespace opencvutil
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement