diff --git a/modules/ximgproc/src/radon_transform.cpp b/modules/ximgproc/src/radon_transform.cpp index 5e23edda5a..a0484de659 100644 --- a/modules/ximgproc/src/radon_transform.cpp +++ b/modules/ximgproc/src/radon_transform.cpp @@ -5,77 +5,80 @@ #include "precomp.hpp" namespace cv {namespace ximgproc { - void RadonTransform(InputArray src, - OutputArray dst, - double theta, - double start_angle, - double end_angle, - bool crop, - bool norm) - { - CV_Assert(src.dims() == 2); - CV_Assert(src.channels() == 1); - CV_Assert((end_angle - start_angle) * theta > 0); +void RadonTransform(InputArray src, + OutputArray dst, + double theta, + double start_angle, + double end_angle, + bool crop, + bool norm) +{ + CV_Assert(src.dims() == 2); + CV_Assert(src.channels() == 1); + CV_Assert((end_angle - start_angle) * theta > 0); - Mat _srcMat = src.getMat(); + int col_num = cvRound((end_angle - start_angle) / theta); + int row_num, out_mat_type; + Point center; + Mat srcMat, masked_src; - int _row_num, _col_num, _out_mat_type; - _col_num = cvRound((end_angle - start_angle) / theta); - transpose(_srcMat, _srcMat); - Mat _masked_src; - cv::Point _center; + transpose(src, srcMat); - if (_srcMat.type() == CV_32FC1 || _srcMat.type() == CV_64FC1) { - _out_mat_type = CV_64FC1; - } - else { - _out_mat_type = CV_32SC1; - } + if (srcMat.type() == CV_32FC1 || srcMat.type() == CV_64FC1) { + out_mat_type = CV_64FC1; + } + else { + out_mat_type = CV_32SC1; + } - if (crop) { - // crop the source into square - _row_num = min(_srcMat.rows, _srcMat.cols); - cv::Rect _crop_ROI( - _srcMat.cols / 2 - _row_num / 2, - _srcMat.rows / 2 - _row_num / 2, - _row_num, _row_num); - _srcMat = _srcMat(_crop_ROI); - // crop the source into circle - Mat _mask(_srcMat.size(), CV_8UC1, Scalar(0)); - _center = Point(_srcMat.cols / 2, _srcMat.rows / 2); - circle(_mask, _center, _srcMat.cols / 2, Scalar(255), FILLED); - _srcMat.copyTo(_masked_src, _mask); - } - else { - // avoid cropping corner when rotating - _row_num = cvCeil(sqrt(_srcMat.rows * _srcMat.rows + _srcMat.cols * _srcMat.cols)); - _masked_src = Mat(Size(_row_num, _row_num), _srcMat.type(), Scalar(0)); - _center = Point(_masked_src.cols / 2, _masked_src.rows / 2); - _srcMat.copyTo(_masked_src(Rect( - (_row_num - _srcMat.cols) / 2, - (_row_num - _srcMat.rows) / 2, - _srcMat.cols, _srcMat.rows))); - } + if (crop) { + // Crop the source into square + row_num = min(srcMat.rows, srcMat.cols); + Rect crop_ROI( + srcMat.cols / 2 - row_num / 2, + srcMat.rows / 2 - row_num / 2, + row_num, row_num); + srcMat = srcMat(crop_ROI); - double _t; - Mat _rotated_src; - Mat _radon(_row_num, _col_num, _out_mat_type); + // Crop the source into circle + Mat mask(srcMat.size(), CV_8UC1, Scalar(0)); + center = Point(srcMat.cols / 2, srcMat.rows / 2); + circle(mask, center, srcMat.cols / 2, Scalar(255), FILLED); + srcMat.copyTo(masked_src, mask); + } + else { + // Avoid cropping corner when rotating + row_num = cvCeil(sqrt(srcMat.rows * srcMat.rows + srcMat.cols * srcMat.cols)); + masked_src = Mat(Size(row_num, row_num), srcMat.type(), Scalar(0)); + center = Point(masked_src.cols / 2, masked_src.rows / 2); + srcMat.copyTo(masked_src(Rect( + (row_num - srcMat.cols) / 2, + (row_num - srcMat.rows) / 2, + srcMat.cols, srcMat.rows))); + } - for (int _col = 0; _col < _col_num; _col++) { - // rotate the source by _t - _t = (start_angle + _col * theta); - cv::Mat _r_matrix = cv::getRotationMatrix2D(_center, _t, 1); - cv::warpAffine(_masked_src, _rotated_src, _r_matrix, _masked_src.size()); - Mat _col_mat = _radon.col(_col); - // make projection - cv::reduce(_rotated_src, _col_mat, 1, REDUCE_SUM, _out_mat_type); - } + Mat radon(row_num, col_num, out_mat_type); - if (norm) { - normalize(_radon, _radon, 0, 255, NORM_MINMAX, CV_8UC1); + // Define the parallel loop as a lambda function + parallel_for_(Range(0, col_num), [&](const Range& range) { + for (int col = range.start; col < range.end; col++) { + // Rotate the source by t + double t = (start_angle + col * theta); + Mat r_matrix = getRotationMatrix2D(center, t, 1); + + Mat rotated_src; + warpAffine(masked_src, rotated_src, r_matrix, masked_src.size()); + + Mat col_mat = radon.col(col); + // Make projection + reduce(rotated_src, col_mat, 1, REDUCE_SUM, out_mat_type); } + }); - _radon.copyTo(dst); - return; + if (norm) { + normalize(radon, radon, 0, 255, NORM_MINMAX, CV_8UC1); } + + radon.copyTo(dst); +} } }