JavaCV version 1.3.2 (OpenCV version 3.2.0)
inRange(srcMat, new Scalar(H_MIN, S_MIN, V_MIN, 0), new Scalar(H_MAX, S_MAX, V_MAX, 0), destMat); will not compile because org.bytedeco.javacpp.opencv_core.inRange() only allows Mat for the lowerb and upperb parameters, instead of Mat or Scalar (i.e. InputArray).
org.bytedeco.javacpp.opencv_core.inRange() should allow opencv_core.Scalar to be an input argument for lowerb and upperb. The documentation for inRange notes that upper and lower bounds can be either Mat or Scalar http://docs.opencv.org/3.2.0/d2/de8/group__core__array.html#ga48af0ab51e36436c5d04340e036ce981
This functionality still works with the old API, so there is org.bytedeco.javacpp.opencv_core.cvInRangeS which takes CvScalar as boundaries and org.bytedeco.javacpp.opencv_core.cvInRange(); which takes CVMat as boundaries. Perhaps a similar solution could work here?
The Java bindings generated by OpenCV seem to able to handle this case, as seen in this sample code for Android in their repo https://github.com/opencv/opencv/blob/05b15943d6a42c99e5f921b7dbaa8323f3c042c6/samples/android/color-blob-detection/src/org/opencv/samples/colorblobdetect/ColorBlobDetector.java
The OpenCV header file in question seems to be core.hpp: https://github.com/opencv/opencv/blob/8ba95cd4985e739433e969cb56e682cfb24ced1a/modules/core/include/opencv2/core.hpp
inRange(srcMat, new Mat(H_MIN, S_MIN, V_MIN, 0), new Mat(H_MAX, S_MAX, V_MAX, 0), destMat);
should work though. The issue with cv::InputArray is that it's not possible to know from the header files if the function accepts cv::Scalar or std::vector<> or just Mat. As far as I know, all of them accept Mat, and if that's the case we might as well just use that. It works just as well. Do you need to use Scalar?
Thanks, I wasn't sure if Scalar was really just a special case of Mat. I won't need to use Scalar if a Mat is functionally equivalent. (Now I just need to write quick a test to convince myself that they are indeed equivalent.)
...Actually, I wrote up the following test case, and it failed, so perhaps there's still a problem?
public static void main(String args[]){
Mat image = imread("img.jpg");
Mat hsv = new Mat();
Mat filtered = new Mat();
int H_MIN = 110;
int H_MAX = 160;
int S_MIN = 0;
int S_MAX = 70;
int V_MIN = 110;
int V_MAX = 256;
cvtColor(image, hsv, CV_BGR2HSV);
inRange(hsv, new Mat(H_MIN, S_MIN, V_MIN, 0), new Mat(H_MAX, S_MAX, V_MAX, 0), filtered);
}
OpenCV Error: Sizes of input arguments do not match (The lower bounary is neither an array of the same size and same type as src, nor a scalar) in cv::inRange, file C:\projects\bytedeco\javacpp-presets\opencv\cppbuild\windows-x86_64\opencv-3.2.0\modules\core\src\arithm.cpp, line 1944
Exception in thread "main" java.lang.RuntimeException: C:\projects\bytedeco\javacpp-presets\opencv\cppbuild\windows-x86_64\opencv-3.2.0\modules\core\src\arithm.cpp:1944: error: (-209) The lower bounary is neither an array of the same size and same type as src, nor a scalar in function cv::inRange
I see, so new Mat(1, 1, CV_32SC4, new IntPointer(H_MIN, S_MIN, V_MIN, 0)) might work then...
Yes that worked. Thanks! - that ends up being a pretty good workaround for this case, especially as that particular Mat constructor will take in a Scalar as an argument,
In summary, I ended up replacing my original call
inRange(srcMat, new Scalar(H_MIN, S_MIN, V_MIN, 0), new Scalar(H_MAX, S_MAX, V_MAX, 0), destMat);
with
`inRange(srcMat, new Mat(1, 1, CV_32SC4, new Scalar(H_MIN, S_MIN, V_MIN, 0)), new Mat(1, 1, CV_32SC4, new Scalar(H_MAX, S_MAX, V_MAX, 0)), destMat);
FYI, I've added new convenience constructors that are now part version 1.4. Enjoy!
Most helpful comment
Yes that worked. Thanks! - that ends up being a pretty good workaround for this case, especially as that particular Mat constructor will take in a Scalar as an argument,
In summary, I ended up replacing my original call
with