@@ -44,31 +44,43 @@ void GeoImgGrid::draw(const GeoImgGrid& other, std::optional<int> interpolation)
4444 transform ().projection_to_pixel (other.transform ().pixel_to_projection ({0 , 0 }));
4545 double dx_ratio = other.transform ().dx () / transform ().dx ();
4646 double dy_ratio = other.transform ().dy () / transform ().dy ();
47- cv::Rect roi (top_left.x (), top_left.y (), other.width () * dx_ratio, other.height () * dy_ratio);
47+ const int full_w = static_cast <int >(other.width () * dx_ratio);
48+ const int full_h = static_cast <int >(other.height () * dy_ratio);
49+ const cv::Rect roi_full (static_cast <int >(top_left.x ()), static_cast <int >(top_left.y ()), full_w,
50+ full_h);
4851 cv::Mat resized_img;
49- cv::resize (*other.m_img , resized_img,
50- cv::Size (other.width () * dx_ratio, other.height () * dy_ratio), 0 , 0 ,
52+ cv::resize (*other.m_img , resized_img, cv::Size (full_w, full_h), 0 , 0 ,
5153 interpolation.value_or (cv::INTER_NEAREST ));
52- if (resized_img.channels () == 4 && m_img->channels () == 4 ) {
54+
55+ const cv::Rect img_bounds (0 , 0 , m_img->cols , m_img->rows );
56+ const cv::Rect roi = roi_full & img_bounds;
57+ if (roi.width <= 0 || roi.height <= 0 ) {
58+ return ;
59+ }
60+ const cv::Rect src_rect (roi.x - roi_full.x , roi.y - roi_full.y , roi.width , roi.height );
61+ cv::Mat resized_roi = resized_img (src_rect);
62+ cv::Mat dest_roi = (*m_img)(roi);
63+
64+ if (resized_roi.channels () == 4 && m_img->channels () == 4 ) {
5365 cv::Mat alpha_other, alpha_m_img;
5466 std::vector<cv::Mat> channels_other, channels_m_img;
55- cv::split (resized_img , channels_other);
56- cv::split ((*m_img)(roi) , channels_m_img);
67+ cv::split (resized_roi , channels_other);
68+ cv::split (dest_roi , channels_m_img);
5769 alpha_other = channels_other[3 ];
5870 alpha_m_img = channels_m_img[3 ];
5971
6072 alpha_other.convertTo (alpha_other, CV_32F , 1.0 / 255.0 );
6173 alpha_m_img.convertTo (alpha_m_img, CV_32F , 1.0 / 255.0 );
6274
63- cv::Mat blended_img = cv::Mat::zeros ((*m_img)(roi) .size (), CV_8UC4 );
75+ cv::Mat blended_img = cv::Mat::zeros (dest_roi .size (), CV_8UC4 );
6476#pragma omp parallel for
65- for (int y = 0 ; y < (*m_img)(roi) .rows ; ++y) {
66- for (int x = 0 ; x < (*m_img)(roi) .cols ; ++x) {
77+ for (int y = 0 ; y < dest_roi .rows ; ++y) {
78+ for (int x = 0 ; x < dest_roi .cols ; ++x) {
6779 float alpha = alpha_other.at <float >(y, x);
6880 float beta = alpha_m_img.at <float >(y, x);
6981
70- cv::Vec4b color_resized = resized_img .at <cv::Vec4b>(y, x);
71- cv::Vec4b color_m_img = (*m_img)(roi) .at <cv::Vec4b>(y, x);
82+ cv::Vec4b color_resized = resized_roi .at <cv::Vec4b>(y, x);
83+ cv::Vec4b color_m_img = dest_roi .at <cv::Vec4b>(y, x);
7284
7385 for (int c = 0 ; c < 3 ; ++c) {
7486 blended_img.at <cv::Vec4b>(y, x)[c] =
@@ -79,9 +91,9 @@ void GeoImgGrid::draw(const GeoImgGrid& other, std::optional<int> interpolation)
7991 }
8092 }
8193
82- blended_img.copyTo ((*m_img)(roi) );
94+ blended_img.copyTo (dest_roi );
8395 } else {
84- resized_img .copyTo ((*m_img)(roi) );
96+ resized_roi .copyTo (dest_roi );
8597 }
8698}
8799void GeoImgGrid::draw_point (const Coordinate2D<double >& point, const ColorVariant& color,
0 commit comments