Log in

View Full Version : Method From ColorImage


Ouroboroz
22-06-2016, 17:20
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:

euhlmann
22-06-2016, 23:40
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.

Peter Johnson
23-06-2016, 13:50
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 :)

Please feel free to create issues on github for these.

Ouroboroz
25-06-2016, 16:05
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.

Wait would casting MonoImage into BinaryImage work too?

euhlmann
25-06-2016, 16:35
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

nickbrickmaster
25-06-2016, 17:46
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.

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.

euhlmann
25-06-2016, 18:04
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.


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

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.

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.


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

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?

nickbrickmaster
25-06-2016, 18:48
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.

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 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?
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.

Ouroboroz
25-06-2016, 22:09
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?

euhlmann
26-06-2016, 13:40
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.