Most efficient way to clamp values in an OpenCv Mat
10,340
Try splitting, using cvThreshold
and then merging. You may also get away with using cvSetImageCOI
to avoid the splitting. I'm not sure if thresholding code supports the COI.
You may want to profile both versions and compare their performance. I have a feeling it will do the same thing.
Author by
Kyle McDonald
Updated on September 15, 2022Comments
-
Kyle McDonald over 1 year
I have an OpenCv
Mat
that I'm going to use for per-pixel remapping, calledremap
, that hasCV_32FC2
elements.Some of these elements might be outside of the allowed range for the remap. So I need to clamp them between
Point2f(0, 0)
andPoint2f(w, h)
. What is the shortest, or most efficient, way of accomplishing this with OpenCv 2.x?Here's one solution:
void clamp(Mat& mat, Point2f lowerBound, Point2f upperBound) { vector<Mat> matc; split(mat, matc); min(max(matc[0], lowerBound.x), upperBound.x, matc[0]); min(max(matc[1], lowerBound.y), upperBound.y, matc[1]); merge(matc, mat); }
But I'm not sure if it's the shortest, or if split/merge is efficient.
-
Kyle McDonald over 12 yearsThanks for the comment, but I'm not sure how
threshold
could be used to do clamping more effectively than I show above withmin
/max
. And after reading a bit more, it looks likesplit
/merge
are the C++ equivalents ofcvSetImageCOI
/cvGetImageCOI
. -
mpenkov over 12 years
split
andmerge
in the C++ interface correspond tocvSplit
andcvMerge
functions in the C interface. Splitting is different to setting the COI -- the former actually moves data from the source to the destination, while the latter just modifies the image object header. Same for merging. Looking for ways to avoiding the split/merge may be your best bet at improving performance. I can't really guarantee that it will be more efficient (you meant efficient, not effective, right?) -- your best bet may be just to compare different implementations and run with the one that is faster. -
Kyle McDonald over 12 yearsYes, definitely meant "efficient" and not "effective". Thanks for clarifying cvSplit/cvMerge, I must have understood the 2.3 refman. I guess there's no 2.x way to do COI then?
-
mpenkov over 12 yearsThere don't seem to be many references to the COI in the C++ section of the manual. Either the C++ COI way is really cryptic, or it doesn't exist. You can still use the old C interface with C++ code (it's a bit ugly but it will work). The underlying storage for
struct IplImage
andcv::Mat
is the same, so you can convert between the two with relatively little overhead. It will make your code uglier, but if using the COI instead of splitting gets the job done, then it may be worth it.