1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 23:33:05 +04:00

Merge pull request #29250 from amd:fast_lut8u_simd

imgproc: optimized LUT and equalizeHist with SIMD #29250

- optimized lut with SIMD
- support equalizeHist with v_lut

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [ ] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Madan mohan Manokar
2026-06-18 19:59:18 +05:30
committed by GitHub
parent d0925fa360
commit 70a2c50b43
20 changed files with 593 additions and 27 deletions
+15 -25
View File
@@ -3321,10 +3321,14 @@ private:
cv::Mutex* histogramLock_;
};
namespace cv {
void equalizeHistLut_dispatch( const uchar* src, uchar* dst, int len, const uchar* lut );
}
class EqualizeHistLut_Invoker : public cv::ParallelLoopBody
{
public:
EqualizeHistLut_Invoker( cv::Mat& src, cv::Mat& dst, int* lut )
EqualizeHistLut_Invoker( cv::Mat& src, cv::Mat& dst, uchar* lut )
: src_(src),
dst_(dst),
lut_(lut)
@@ -3337,7 +3341,7 @@ public:
int width = src_.cols;
int height = rowRange.end - rowRange.start;
int* lut = lut_;
const uchar* lut = lut_;
if (src_.isContinuous() && dst_.isContinuous())
{
@@ -3350,26 +3354,7 @@ public:
for (; height--; sptr += sstep, dptr += dstep)
{
int x = 0;
for (; x <= width - 4; x += 4)
{
int v0 = sptr[x];
int v1 = sptr[x+1];
int x0 = lut[v0];
int x1 = lut[v1];
dptr[x] = (uchar)x0;
dptr[x+1] = (uchar)x1;
v0 = sptr[x+2];
v1 = sptr[x+3];
x0 = lut[v0];
x1 = lut[v1];
dptr[x+2] = (uchar)x0;
dptr[x+3] = (uchar)x1;
}
for (; x < width; ++x)
dptr[x] = (uchar)lut[sptr[x]];
cv::equalizeHistLut_dispatch(sptr, dptr, width, lut);
}
}
@@ -3383,7 +3368,7 @@ private:
cv::Mat& src_;
cv::Mat& dst_;
int* lut_;
uchar* lut_;
};
CV_IMPL void cvEqualizeHist( const CvArr* srcarr, CvArr* dstarr )
@@ -3464,10 +3449,9 @@ void cv::equalizeHist( InputArray _src, OutputArray _dst )
const int hist_sz = EqualizeHistCalcHist_Invoker::HIST_SZ;
int hist[hist_sz] = {0,};
int lut[hist_sz];
int lut[hist_sz] = {0,};
EqualizeHistCalcHist_Invoker calcBody(src, hist, &histogramLockInstance);
EqualizeHistLut_Invoker lutBody(src, dst, lut);
cv::Range heightRange(0, src.rows);
if(EqualizeHistCalcHist_Invoker::isWorthParallel(src))
@@ -3494,6 +3478,12 @@ void cv::equalizeHist( InputArray _src, OutputArray _dst )
lut[i] = saturate_cast<uchar>(sum * scale);
}
uchar lut_u8[hist_sz];
for (int j = 0; j < hist_sz; ++j)
lut_u8[j] = (uchar)lut[j];
EqualizeHistLut_Invoker lutBody(src, dst, lut_u8);
if(EqualizeHistLut_Invoker::isWorthParallel(src))
parallel_for_(heightRange, lutBody);
else