18 #ifndef CV_FUNCTIONS_HPP
19 #define CV_FUNCTIONS_HPP
26 #if defined(VIZ_DEBUG) || defined(VIZ_DEBUG_SEG)
27 #include <opencv2/core.hpp>
28 #include <opencv2/imgproc/imgproc.hpp>
31 #include <Eigen/Dense>
32 #include <unsupported/Eigen/MatrixFunctions>
34 #include "modules/utility/dataTypes.hpp"
50 void convexHull(
const std::vector<Eigen::Vector2d> &points, std::vector<Eigen::Vector2d> &hull);
57 void convexHull(
const std::vector<Eigen::Vector2f> &points, std::vector<Eigen::Vector2f> &hull);
78 inline Eigen::Vector2f convertOcvPtToEigenPt(
const cv::Point2d pt_ocv)
81 pt_e << pt_ocv.x, pt_ocv.y;
94 const float minX=0,
const float minY=0,
const float width=0,
const float height=0
97 Eigen::Vector2f
min(minX, minY);
98 Eigen::Vector2f
max(minX +
width, minY + height);
114 Eigen::Vector2f
min = bbox.min();
115 Eigen::Vector2f
max = bbox.max();
116 min(0) += displacement_x;
117 max(0) += displacement_x;
118 min(1) += displacement_y;
119 max(1) += displacement_y;
130 const Eigen::Vector2f
min = bbox.min();
131 const Eigen::Vector2f
size = bbox.sizes();
142 std::stringstream out;
143 out <<
"[" << bbox.sizes()(0) <<
" x " << bbox.sizes()(1) <<
" from (" << bbox.min()(0) <<
", " << bbox.min()(1) <<
")]";
154 return bbox1.min() == bbox2.min() && bbox1.max() == bbox2.max();
164 return ((a % b) + b) % b;
175 Eigen::Vector2f min_new = bbox.min();
176 Eigen::Vector2f max_new = bbox.max();
178 const float width_prev = max_new(0) - min_new(0);
179 const float height = max_new(1) - min_new(1);
180 const float width_new = height * aspectRatio;
181 min_new(0) -= (width_new - width_prev) / 2.0;
182 max_new(0) += (width_new - width_prev) / 2.0;
187 #if defined(VIZ_DEBUG) || defined(VIZ_DEBUG_SEG)
194 Eigen::Vector2f
min;
min << bbox.x, bbox.y;
195 Eigen::Vector2f
max;
max << bbox.x + bbox.width, bbox.y + bbox.height;
206 Eigen::Vector2f
min = bbox.min();
219 assert(x.rows() >= 4 || x.cols() >= 4);
224 double w = useAspc ? x(2) * h : x(2);
237 Eigen::RowVectorXf hann_rows(height);
238 Eigen::RowVectorXf hann_cols(
width);
241 int offset_y = NN * offsetFactor_y;
245 for (
int i = 0; i < height; ++i)
247 int i_p = i-offset_y > height ? 0 : i-offset_y;
248 hann_rows(i) = (float)(1.0/2.0 * (1.0 -
cos(2*M_PI*(i_p)/NN)));
254 for (
int i = 0; i <
width; ++i)
256 hann_cols(i) = (float)(1.0/2.0 * (1.0 -
cos(2*M_PI*i/NN)));
272 const float areaPrev = prevBox.volume();
273 const float areaCurr = currBox.volume();
275 if(prevBox.isEmpty() || areaPrev < std::numeric_limits<float>::epsilon()
276 || currBox.isEmpty() || areaCurr < std::numeric_limits<float>::epsilon())
279 float sizeRatio = areaCurr / areaPrev;
282 sizeRatio = 1.f / sizeRatio;
293 inline Eigen::MatrixXf
circshift(
const Eigen::MatrixXf &matrix,
int dx,
int dy)
295 Eigen::MatrixXf matrix_out(matrix.rows(), matrix.cols());
296 const int rows = matrix.rows();
297 const int cols = matrix.cols();
300 for(
int i=0; i<rows; i++) {
301 for(
int j=0; j<cols; j++) {
302 idx_y =
modul(i+dy, rows);
303 idx_x =
modul(j+dx, cols);
304 matrix_out(idx_y, idx_x) = matrix(i,j);
317 inline Eigen::MatrixXf
get2dGaussianPdf(
const float sigma,
const int w,
const int h,
const bool wrap_kernel =
true)
319 Eigen::MatrixXf y(h, w);
320 float w2 =
static_cast<float>(int(w/2));
321 float h2 =
static_cast<float>(int(h/2));
324 for(
int i=0; i<h; i++) {
325 for(
int j=0; j<w; j++) {
326 y(i,j) = (float)
exp((-0.5 /
pow(sigma, 2)) * (
pow((i-h2), 2) +
pow((j-w2), 2)));
351 Eigen::Vector2f min_new = tBbox_new.min();
352 Eigen::Vector2f max_new = tBbox_new.max();
353 const float w_new = tBbox_new.sizes()(0);
354 const float h_new = tBbox_new.sizes()(1);
356 const float w_prev = tBbox_prev.sizes()(0);
357 const float h_prev = tBbox_prev.sizes()(1);
359 const float w_src = srcImageBox.max()(0);
360 const float h_src = srcImageBox.max()(1);
363 if(w_prev > w_new && min_new(0) <= 1)
365 min_new(0) = max_new(0) - w_prev;
369 if(w_prev > w_new && max_new(0) > w_src - 1)
371 max_new(0) = min_new(0) + w_prev;
375 if(h_prev > h_new && min_new(1) <= 1)
377 min_new(1) = max_new(1) - h_prev;
381 if(h_prev > h_new && max_new(1) > h_src - 1)
383 max_new(1) = min_new(1) + h_prev;
398 const Eigen::Vector2f min_new = bbox_new.min();
399 const float newW = bbox_new.sizes()(0);
400 const float newH = bbox_new.sizes()(1);
402 Eigen::Vector2f centerPt;
404 centerPt << min_new(0) + newW / 2.0f, min_new(1) + newH / 2.0f;
406 float searchRegionSize_w =
static_cast<float>(
floorf(newW + paddingScale*
sqrt(newW * newH)));
407 float searchRegionSize_h =
static_cast<float>(
floorf(newH + paddingScale*
sqrt(newW * newH)));
408 searchRegionSize_w = (searchRegionSize_w + searchRegionSize_h) / 2.0f;
409 searchRegionSize_h = searchRegionSize_w;
413 centerPt(0) - searchRegionSize_w/2.f, centerPt(1) - searchRegionSize_h/2.f,
414 searchRegionSize_w, searchRegionSize_h
427 const float areaPrev = prevBox.volume();
428 const float areaCurr = currBox.volume();
430 if(prevBox.isEmpty() || areaPrev < std::numeric_limits<float>::epsilon()
431 || currBox.isEmpty() || areaCurr < std::numeric_limits<float>::epsilon())
434 if(currBox.intersects(prevBox))
436 float intersection = currBox.intersection(prevBox).volume();
437 float union_area = areaCurr + areaPrev - intersection;
439 if(union_area < std::numeric_limits<float>::epsilon() || intersection < std::numeric_limits<float>::epsilon())
445 return intersection / union_area;
461 if(imgBbox.isEmpty() || imgBbox.volume() < std::numeric_limits<float>::epsilon()
462 || objBbox.isEmpty() || objBbox.volume() < std::numeric_limits<float>::epsilon())
465 if(objBbox.intersects(imgBbox))
467 float intersection = objBbox.intersection(imgBbox).volume();
469 if(intersection < std::numeric_limits<float>::epsilon())
475 float iou = intersection / objBbox.volume();
493 inline int orientation(
const Eigen::Vector2d& p,
const Eigen::Vector2d& q,
const Eigen::Vector2d& r)
495 float val = (q(1) - p(1)) * (r(0) - q(0)) -
496 (q(0) - p(0)) * (r(1) - q(1));
499 if (
val == 0.)
return 0;
501 return (
val > 0) ? 1 : 2;
511 inline int orientation(
const Eigen::Vector2f& p,
const Eigen::Vector2f& q,
const Eigen::Vector2f& r)
513 float val = (q(1) - p(1)) * (r(0) - q(0)) -
514 (q(0) - p(0)) * (r(1) - q(1));
517 if (
val == 0.)
return 0;
519 return (
val > 0) ? 1 : 2;
530 inline cv::Mat
circshift(cv::Mat matrix,
int dx,
int dy)
532 cv::Mat matrix_out = matrix.clone();
535 for(
int i=0; i<matrix.rows; i++) {
536 for(
int j=0; j<matrix.cols; j++) {
537 idx_y =
modul(i+dy, matrix.rows);
538 idx_x =
modul(j+dx, matrix.cols);
539 matrix_out.at<
float>(idx_y, idx_x) = matrix.at<
float>(i,j);
556 inline void OverlayImage(
557 const cv::Mat &background,
const cv::Mat &foreground, cv::Mat &output,
558 cv::Point2i location = cv::Point(0,0),
const cv::Mat &foregroundDensityMap = cv::Mat(),
559 float opacity_min = 0,
float opacity_offset = 1,
float opacity_scale = 1
562 if(background.cols != output.cols || background.rows != output.rows || background.type() != output.type() || background.channels() != output.channels())
563 background.copyTo(output);
566 for(
int y =
std::max(location.y , 0); y < background.rows; ++y)
569 int fY = y - location.y;
572 if(fY >= foreground.rows)
576 for(
int x =
std::max(location.x, 0); x < background.cols; ++x)
579 int fX = x - location.x;
582 bool isFilled =
false;
583 for(
int c = 0; c < output.channels(); ++c)
584 isFilled |= foreground.data[fY*foreground.step + fX*foreground.channels() + c];
590 if(fX >= foreground.cols)
594 double opacity_fg = 0;
596 if(foregroundDensityMap.rows > 0 && foregroundDensityMap.at<
float>(fY,fX) > opacity_min)
600 std::min(
double(1.),
double(foregroundDensityMap.at<
float>(fY,fX)*opacity_scale + opacity_offset))
603 unsigned char foregroundPx, backgroundPx;
604 for(
int c = 0; opacity_fg > 0 && c < output.channels(); ++c)
606 foregroundPx = foreground.data[fY*foreground.step + fX*foreground.channels() + c];
607 backgroundPx = background.data[y*background.step + x*background.channels() + c];
609 output.data[y*output.step + output.channels()*x + c] = backgroundPx*(1.-opacity_fg) + foregroundPx*opacity_fg;
620 inline cv::Point2f ConverPtBtwPlanes(
const cv::Point2f &pt,
const cv::Mat &projMat_A2B)
622 cv::Mat pt_homo = cv::Mat(3,1,projMat_A2B.type());
623 pt_homo.at<
double>(0,0) = pt.x;
624 pt_homo.at<
double>(1,0) = pt.y;
625 pt_homo.at<
double>(2,0) = 1.;
627 cv::Mat temp = projMat_A2B * pt_homo;
629 cv::Point2f pt_transformed(temp.at<
double>(0,0)/temp.at<
double>(2,0), temp.at<
double>(1,0)/temp.at<
double>(2,0));
631 return pt_transformed;
639 inline void Density2Opacity(
const cv::Mat &input, cv::Mat &output)
651 inline bool warpPerspective_custom(
const cv::Mat &inImg, cv::Mat &outImg,
const cv::Mat &projMat_In2out)
653 outImg = cv::Mat(inImg.cols, inImg.rows, inImg.type(), cv::Scalar(0));
656 cv::Mat projMat_Out2In = projMat_In2out.inv();
658 for(
int y = 0; y < outImg.rows; ++y)
660 for(
int x = 0; x < outImg.cols; ++x)
662 cv::Point2f pt_in = ConverPtBtwPlanes(cv::Point2f(x,y), projMat_Out2In);
665 if(pt_in.x >= inImg.cols || pt_in.y >= inImg.rows || pt_in.x < 0 || pt_in.y < 0)
668 for(
int c = 0; c < outImg.channels(); ++c)
670 outImg.data[y*outImg.step + x*outImg.channels() + c] = inImg.data[int(pt_in.y+0.5)*inImg.step + int(pt_in.x+0.5)*inImg.channels() + c];
685 inline bool getTransformedPixelDensity(
const cv::Mat &inImg, cv::Mat &densityImg,
const cv::Mat &projMat_In2out)
688 densityImg = cv::Mat(inImg.rows, inImg.cols, CV_32F, cv::Scalar(0));
692 for(
uint y = 0; y < densityImg.rows-STEP; y += STEP)
694 for(
uint x = 0; x < densityImg.cols-STEP; x += STEP)
696 cv::Point2f pt_in_1 = ConverPtBtwPlanes(cv::Point2f(x,y), projMat_In2out);
697 cv::Point2f pt_in_2 = ConverPtBtwPlanes(cv::Point2f(x+1,y+1), projMat_In2out);
698 float dist_sq =
pow(pt_in_1.x - pt_in_2.x,2) +
pow(pt_in_1.y - pt_in_2.y,2);
700 float density = 1./dist_sq;
702 for(
uint m=0; m<STEP; m++)
703 for(
uint n=0; n<STEP; n++)
704 densityImg.at<
float>(y+m,x+n) = density;
707 cv::normalize(densityImg, densityImg, 0, 1, cv::NORM_MINMAX, CV_32F);
717 inline bool isFileExists(
const std::string& filename)
720 if (stat(filename.c_str(), &buf) != -1)
731 inline cv::Mat NV12_to_BGR(
const cv::Mat nv12_img)
733 assert(nv12_img.channels() == 1);
736 cv::cvtColor(nv12_img, bgr_img, cv::COLOR_YUV2BGR_NV12);
747 inline cv::Mat NV12_to_BGR(
unsigned char* yuv_data,
unsigned int width,
unsigned int height)
749 cv::Mat nv12_img = cv::Mat(height * 3/2,
width, CV_8UC1, yuv_data);
751 cv::cvtColor(nv12_img, bgr_img, cv::COLOR_YUV2BGR_NV12);
760 inline cv::Mat BGR_to_NV12(
const cv::Mat src)
762 assert(src.type() == CV_8UC3);
765 cv::Mat dst = cv::Mat::zeros(cv::Size(src.size().width, src.size().height*1.5), CV_8UC1);
768 for(
int y=0; y<src.rows; y++)
770 for(
int x=0; x<src.cols; x++)
772 const cv::Vec3b bgr = src.at<cv::Vec3b>(cv::Point(x,y));
773 const uchar B = bgr.val[0];
774 const uchar G = bgr.val[1];
775 const uchar R = bgr.val[2];
779 Y = 0.257*R + 0.504*G + 0.098*B + 16 + 0.5f;
783 for(
int y=0; y<src.rows; y+=2)
785 for(
int x=0; x<src.cols; x+=2)
787 const cv::Vec3b bgr = src.at<cv::Vec3b>(cv::Point(x,y));
788 const uchar B = bgr.val[0];
789 const uchar G = bgr.val[1];
790 const uchar R = bgr.val[2];
792 uchar &Cb = dst.at<
uchar>(cv::Point(x+0,y/2+src.rows));
793 uchar &Cr = dst.at<
uchar>(cv::Point(x+1,y/2+src.rows));
795 Cb = -0.148*R - 0.291*G + 0.439*B + 128;
796 Cr = 0.439*R - 0.368*G - 0.071*B + 128;
807 inline cv::Mat BGR_to_NV12_2ch(
const cv::Mat src)
809 assert(src.type() == CV_8UC3);
812 std::vector<cv::Mat> dst_per_ch(2);
813 dst_per_ch[0] = cv::Mat::zeros(src.size(), CV_8UC1);
814 dst_per_ch[1] = cv::Mat::zeros(src.size(), CV_8UC1);
817 for(
int y=0; y<src.rows; y++)
819 for(
int x=0; x<src.cols; x++)
821 const cv::Vec3b bgr = src.at<cv::Vec3b>(cv::Point(x,y));
822 const uchar B = bgr.val[0];
823 const uchar G = bgr.val[1];
824 const uchar R = bgr.val[2];
826 uchar &Y = dst_per_ch[0].at<
uchar>(cv::Point(x,y));
828 Y = 0.257*R + 0.504*G + 0.098*B + 16 + 0.5f;
832 for(
int y=0; y<src.rows; y+=2)
834 for(
int x=0; x<src.cols; x+=2)
836 const cv::Vec3b bgr = src.at<cv::Vec3b>(cv::Point(x,y));
837 const uchar B = bgr.val[0];
838 const uchar G = bgr.val[1];
839 const uchar R = bgr.val[2];
841 uchar &Cb = dst_per_ch[1].at<
uchar>(cv::Point(x+0,y/2));
842 uchar &Cr = dst_per_ch[1].at<
uchar>(cv::Point(x+1,y/2));
844 Cb = -0.148*R - 0.291*G + 0.439*B + 128;
845 Cr = 0.439*R - 0.368*G - 0.071*B + 128;
852 cv::merge(dst_per_ch, dst);
861 inline cv::Mat NV12_2ch_to_BGR(cv::Mat src)
863 assert(src.channels() == 2);
865 std::vector<cv::Mat> nv12_per_ch;
868 cv::split(src, nv12_per_ch);
870 cv::Mat nv12_img = cv::Mat::zeros(cv::Size(src.size().width, src.size().height*3/2), CV_8UC1);
873 nv12_per_ch[0].copyTo(nv12_img(
cv::Rect(0,0,src.size().width,src.size().height) ));
877 cv::Rect(0,0,src.size().width,src.size().height*0.5)
878 ).copyTo(nv12_img(
cv::Rect(0,src.size().height,src.size().width,src.size().height*0.5) ));
881 cv::cvtColor(nv12_img, bgr_img, cv::COLOR_YUV2BGR_NV12);
890 #endif // CV_FUNCTIONS_HPP