Method From ColorImage

So the code for the threshold method is:

private BinaryImage threshold(NIVision.ColorMode colorMode, int low1, int high1, int low2,
int high2, int low3, int high3) throws NIVisionException {
BinaryImage res = new BinaryImage();
NIVision.Range range1 = new NIVision.Range(low1, high1);
NIVision.Range range2 = new NIVision.Range(low2, high2);
NIVision.Range range3 = new NIVision.Range(low3, high3);
NIVision.imaqColorThreshold(res.image, image, 1, colorMode, range1, range2, range3);
res.free();
range1.free();
range2.free();
range3.free();
return res;
}

I’m confused on the part where res is freed and the returned afterwards. If I read correctly, free() releases the memory for the image. So would return still give back the image.

PS How do I initialize a Binary Image? The constructor is not public. D:

  1. Yeah, that doesn’t make a lot of sense. Maybe free() doesn’t always do what we think it does? (not likely)

  2. Reflection!


Constructor<BinaryImage> ct = BinaryImage.class.getDeclaredConstructor();
ct.setAccessible(true);
BinaryImage img = ct.newInstance();

Or modify WPILib and compile it together with your project, probably a solution that makes more sense.

  1. It’s a bug, introduced in https://github.com/wpilibsuite/allwpilib/commit/3c4a1d9a1ac201e71dbce9c42070d994ed36ff86 … originally the res.free() was only called if an exception was raised.

  2. By calling ColorImage.threshold(), clearly :slight_smile:

Please feel free to create issues on github for these.

Wait would casting MonoImage into BinaryImage work too?

No, because you can only downcast an object if it was that type to begin with.


class A {}
class B extends A {}

public static void main(String] args){
    A a1 = new B();
    B a1_b = (B) a1; // ok

    A a2 = new A();
    B a2_b = (B) a2; // ClassCastException
}

More info: https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

Ew. If it’s not visible, it’s not meant to be accessible. Reflection is not a tool that should be used in this context. If it’s an API, it’s not meant to be modified and compiled with your project. Use the tools correctly, and your problems will decrease. Use them incorrectly, and they will multiply.

As for an actual answer, you’re not supposed to initialize a BinaryImage. You get them from methods like this one.

Yes, reflection is only to be used when you know what you’re doing, hence my suggestion to modify WPILib instead.

The WPILib people actually have instructions on screensteps for compiling WPILib with your project. I don’t think they would do that if they didn’t want you to modify WPILib.

I don’t really think that’s a good answer. The C++ IMAQ API (although different from this java wrapper) allows creating binary images. Why shouldn’t the Java API allow that?

My answer was more about general API usage than WPILib, I guess. You shouldn’t need to modify an API to get a function working that was part of the library initially.

I didn’t know that, sorry. I’m not too well versed in WPILib vision, and a cursory glance through the docs made it look as if this was the way to do things. My sincere apologies.

Okay so from reading what above ^. I’m assuming the best way to create work with ColorImage.threshold() and initializing a BinaryImage is to compile WPI?

Well the point is that if you need to be able to construct a BinaryImage yourself, you should get your own copy of the wpilib source, make a public constructor for BinaryImage, and compile it together with your project.