I'm a complete newbie in the computer vision world and recently I implemented some examples using OpenCV with Java. I'm impressed with the potential this area has and wish to continue learning more.
I learned that OpenCV is written in C++ and while Java has a wrapper (JavaCV) I understood that the applications in Java are slower than in C++ and most enterprise application are written in C++.
My question is this: I have few years of experience in Java and I feel very comfortable to write any application with it; would it be smart to move to C++ to learn CV or should I stick with Java and use its wrapper.
Computer vision is a demanding area - and while it is true that you'd best stay with what you know, and move to opencv only if performance is needed, another truth is that you'll need to go deep into mathematics, pointers and algorithms to learn and build a good computer vision app. And to do that in Java can be more cumbersome than learning c++.
So, if all you want to do is to apply a filter over an image for some school project - go for Java. But if you want to stay more with OpenCV, to learn vision algorithms or to write your own, my strong suggestion is to learn C++ - isn't that scary!
A reason to write native code is flexibility - you'll want to do all kind of tricks that are difficult or performance-killers in Java.
Shortly speaking, learning C++ is much simpler than computer vision. And OpenCV is not just a library you want to call to do some processing out there. It's bleeding edge technology - you'll want to understand it, to hack into it, to build over it, to go through the code, much more than call someJNIfunc();
And if you do so, please be aware that OpenCV offers two interfaces - one for C and one for C++. And while they offer the same functionality, the C++ one is much like Java - with automatic memory management and more sweeties. You can refer to this post to see the differences
I suggest sticking with what you're comfortable with for now. Only switch to C++ when you find that it doesn't expose certain APIs you want or performance actually becomes a problem. Right now, you're in the learning phase.
JavaCV uses a wrapper called JavaCPP to call OpenCV from Java programs. JavaCPP automatically generates temporary native libraries that form a bridge used by JNI to let Java programs call the OpenCV native libraries.
The solution is elegant and it works well, but is quite finicky about installing just the right versions and having classpaths set correctly. You can get a glimpse of the difficulties people face at the JavaCV discussion forum, and at http://code.google.com/p/javacv/wiki/Windows7AndOpenCV.
I got this working with OpenCV-2.3.1 on XP, Windows 7, and Ubuntu 10.11, and still it took me several days to get it all updated to OpenCV-2.4.2. ffmpeg is especially tricky to get right across all platforms.
There is little or no speed overhead if you are using Java for high level program control because image objects and list-based data structures are maintained on the native side through pointers. One pitfall is knowing who is responsible for releasing allocated memory, so be prepared for VM crashes with complicated programs.
There is a bit overhead in transferring data objects to the Java side. I find that it takes about 1 microsecond to copy a keypoint location into a Java-side Point object. This doesn't sound like much but in a real-time application with thousands of keypoints it can make a difference. We also copy JavaCV IplImage objects to Java through ByteBuffers. This takes a millisecond or less so is quite feasible for real-time use.
In our case, we have a substantial body of Java code to leverage against OpenCV. And Java's garbage collection makes many things much much easier. I are satisfied that the overhead of learning JavaCV has been well worth it.
I found it necessary to build the project in Eclipse and compile JavaCV from source instead of using javacv.jar. (You'll need the other .jar files though.) This lets you examine exceptions to track down library version and classpath errors. And the JavaCV source is needed to understand how JavaCV exposes the OpenCV API.
How much time is spent in the OpenCV library and how much time is spend in your program? If your program entirely in C++ it cannot reduce the time spent in your program (outside the library) to less than nothing. e.g. if you spend 99% of your time in the library, using C++ cannot make it more than 1% faster.
For simple programs, Java and C++ doesn't make any significant difference in speed. But for a large code with lot of computational complexity, C++ turns out to be faster.
Wrappers do have a problem of overhead. But this will be negligible for a small program. If you write a complex code in Java, it wont be easy to rewrite it into C++. This is because of the large no of functions available in Java which will be so much different from C++.
Whether you should use Java or C++ for OpenCV depends on your motive.
If you seriously want to lean OpenCV and work on some big projects , I suggest you to move on to C++. But if you are looking for having just some fun with OpenCV, it will be better to stick to what you know.
Among C++ or Java, better use C++. I have almost no experience in Java, but the reason I would recommend C++ is its common usage among ML&CV libraries.
One of the best solution of powerful and flexible computer vision application may be next sequence:
training a model using flexible Python and popular machine learning libraries;
storing pre-trained weights;
rewriting the best model architechture to C++ using OpenCV library with useful, but not extensive Mat class or compiling to C++ ML model;
compiling with definite specification of your device processor.
Advances of this solution are application work speed, code safety, development speed and compatibility with many devices.
Moreover, Python Tensorflow and other models could be loaded to C++, e.g. PyTorch.
Besides, it is much more easier to get help from CV community with the C++ OpenCV code.
Disadvantages are tons of development problems and development speed (which may not be omitted with Java), sometimes strictful flexibility limits of OpenCV lib, and many others you may not think of at the beginning.
Related
I'm implementing an algorithm for pathfinding that is a variant of A* (HPA*) but with a triangulated search space. I've been making a Java application and have written a good amount of code, but I recently found a C++ library that already takes care of the triangulations for the project. I have several options but I'm not sure what I should do: convert the library to Java or integrate the C++ code into my Java library. I could also rewrite my code in C++ but I'm not very familiar with the language.
This application tests the performance of an algorithm for a paper I'm writing so it doesn't need to be portable. What do you think my best option is?
If you really want to call C++ code from Java, read up on the Java Native Interface (JNI) coding conventions.
But generally, unless you have an extremely good reason to cross languages, it's more trouble than it's worth. How complicated is the triangulation code? If it's less than a few hundred lines, I'd suggest reimplementing; if it's more than a few thousand, using a library may be justified but you should probably check whether there's a Java library available or if someone has already written the appropriate JNI glue code.
It seems like that working with jni will become my everyday routine for a few months. Is there any some tools which simplify dealing with mixed Java + C++ projects?
Is it possible to re-generate glue *.h files and rebuild native libraries automatically? Or I should write some scripts for maven, ant, gradle, anything_else?
Is there any experience?
Check out JavaCPP! I also list other solutions on that page... There's also Jace that is useful when trying to use Java from C++.
Some months ago I faced the same questions. It seems that Java/C++ interop is reviving just now, and that you are one of the pioneers.
If you're merely using C++ objects from Java, JNA may be a better solution.
If you're using Java from C++, I didn't yet encounter a mature library. Although functionally quite complete, JNI is is a C api (intentionally, if you read the design rationale). If you are about to write lots of code for it, I think it'll pay to write a C++ framework around it that wraps the bare jobject ,jnienv, jclass... handles into explicit resources.
The real issues arise when the C++ and Java have to co-operate using callbacks etc... Buckle up if that's your intent...
You are asking about an experience. So my experience is, that you should start with very well designed requirements, behavior and objects lifecycle. That should result in a mature interface which will change very little in the future. The effect is that you will need to change the glue header files rarely and simple one shot javah is good enough. It all doesn't sound very agile i know, but then JNI is everything but a rapid development environment.
Changing the interface twice a day, adding and removing methods and changing signatures "just to see if it helps" is a sure road to hell. You are connecting two very different worlds in terms of memory management and JVM can get nervous very easily. Thread safety is yet another level up. The mentioned helper solutions, while they are undoubtely a clever piece of software, might give you a false perception that JNI is easy. Then JVM starts giving you exceptions out of nowhere, your objects will start geting uninitalized randomly, etc...
You can use SWIG to automatically generate glue code and have an make target to rebuild the native libraries. You can also use ANT's c++ task for the same purpose.
I'm looking for some way of using the number-crunching ability of a GPU (with Java perhaps?) in addition to using the multiple cores that the target machine has. I will be working on implementing (at present) the A* Algorithm but in the future I hope to replace it with a Genetic Algorithm of sorts. I've looked at Project Fortress but as I'm building my GUI in JavaFX, I'd prefer not to stray too far from a JVM.
Of course, should no feasible solution be available, I will migrate to the easiest solution to implement.
If you're interested in HPC with GPUs then perhaps you can look jCuda. This provides Java bindings for CUDA, along with access to CUDA FFT, CUDA BLAS and CUDA DPP. I haven't seen any performance reports on this library so I can't guarantee it will be very good.
Beyond that, I'm not really sure. If you're interested in doing this type of stuff as an educational exercise then Java should be good enough, but if you have a serious need for HPC then you're probably going to want to implement in C and use the Java Native Interface to communicate with it.
Morten Nobel Joergensen has a blog post showing how to create a Mandelbrot Set using JOGL - Java Bindings for OpenGL
However if you want generic computing, rather than graphics, then you'd be after the Java bindings for OpenCL, from which you can chose from JOCL, or JOCL or JavaCL.
Wikipedia's page shows how OpenCL can be used to compute a fast fourier transform.
Parallel Colt might be of interest.
Have a look at JPPF, it is a very nice and mature open source Java grid computing environment
Are there inexpensive or free gateways from .NET to Java? I'm looking at some data acquisition hardware which has drivers for C/C++ and .NET -- I really don't want to do any programming in .NET.
Update: I haven't done what I originally wanted to do, but I've done something similar, using JNA to encapsulate some functions from a DLL, in order to control a USB hardware device from Java. (the DLL comes from the device manufacturer) It works really nicely. Thanks!
You could also try to use JNA for accessing the native library. JNA provides Java programs easy access to native shared libraries (DLLs on Windows) without writing anything but Java codeāno JNI or native code is required. If their API is fairly straight foward, this might be the path of least resistance.
See their getting started guide where they call some native code (printf and GetSystemTime).
Well, there's JNBridge and EZ JCom, just from a Google search.
You could also use IKVM which is a slightly different approach.
(Any reason for not wanting to learn .NET, out of interest? It's a nice platform, and C# is a lovely language...)
If they have C++ versions of the drivers then you could write a wrapper around it using JNI and then load that in Java. JNI can be a bit of a pain, but it would let you use the C++ version of their drivers and not have to deal with .Net at all if you don't want.
I am partial to the recommendation to jump in the deep end with C# since it is so similar to Java. I did this and used IKVM to compile my favorite Java libs. to .NET assemblies and you get [nearly] all the core java runtime classes to boot, so if you tire of trying to find just the right C# collection type, you can always go back to java.util. (No generic collections though. Not sure why.)
Depending on what platform you're on, you have several choices for free IDEs too. For windows you can get Visual Studio Express for free but I also use SharpDevelop. You can also get the Mono IDE on Linux (and a few flavours of Unix, I think ?).
The C# learning curve is shallow if you already know Java. I only blew off 1.5 limbs on landmines that came out of nowhere for reasons I still don't understand, but workarounds were easy to come by. The worst thing about it was the darn developer docs which are AWFUL on account of being so slow. I really miss the snappiness of JavaDoc. Not only are the online docs incredibly slow, the problem is compounded by someones's iffy decision to put class summaries, constructors and methods/properties all on seperate pages so it just takes forever. Someone said to get the docs installer and install docs locally for a slightly improved experience. Not a bad idea I suppose.
I am author of jni4net, open source interprocess bridge between JVM and CLR. It's build on top of JNI and PInvoke. No C/C++ code needed. I hope it will help you.
If you have a Java application, the JNI mentioned by the others will be the way to go. You write some wrapper classes, and that's it.
If writing the wrappes is a too big task (depending on the number of methods you have to wrap), have a look at SWIG . I think it generates wrappers automatically, but I never actually used it.
If you want to code in the Java language, but you don't care if your program will run on the JRE/JVM, then you might as well use Microsoft J#. Basically, it's writing Java-Code wich is compiled to .NET-Bytecode and can use the .NET classes of the driver as well as your existing Java classes. With J# you will run into problems if your existing Java-code is newer than Java 1.4, look at this question on how to solve them.
From that point on, you could later add code in J#, C# or any other .NET language. However, you won't get back to the JRE/JVM easily.
I'm a highly skilled Java dev contemplating learning iPhone development. Mac only dev aspects aside, how much of a leap would learning the mobile application stack be? Sure I understand that its closer to C in how one should approach it, and with that comes memory management and so on.
My queries would also include
How well is OOP/OOAD supported?
Is there some API(s) which enable unit testing?
I'd encourage those who answer to quote external sites and references to help elaborate the detail
The development language is Objective-C, which is pure C with a very thin object wrapper over the top. They syntax is kind of weird looking, but it's pretty easy to get to grips with if you know C once you get over the message calls - myself I have a solid C background and only started picking up Objective-C a month or two so back but I'm finding it really rather pleasing - more so than C++.
The difficulty you're going to have if you have only coded Java is pointers and memory management. Memory management isn't conceptually hard as it's simply (!) a question of keeping track of what you are allocating and releasing, plus XCode seems to come with good tools for detecting leaks (although I haven't used these in anger yet) - and as iPhone programs are relatively small it's not like coding a big system program where this can be extremely tough. The major conceptual difficulty you are likely to have is simply getting your head around pointers as they are used extensively (as in just about on every line of code) and you do need to grok these completely. One of Joel's reoccuring themes on the podcast is the difficulty some coders get using pointers, so I'd recommend you take that carefully and possibly pick up a good book - perhaps the original K&R.
Someone may like to correct me, but although the Cocoa API appears excellent, there seem to be few libraries available outside the framework (unlike C++ or Java). For instance I had to add my own queue and stack classes - although the NSMutableArray makes that extremely easy.
All in all though I'm certainly finding it one the most fun platforms to play with I've used for a while.
A few months ago I was a Java web programmer who hadn't touched C since college. Now I've got one iPhone app completed (for my day job, stuck in the bureaucracy there so it's not in the app store yet) and my second app nearing completion.
To answer your question the biggest hurdles are understanding the conventions (Delegate pattern, Categories, etc.), getting a grasp on memory management, and working with XCode (a good IDE but definitely steps behind Eclipse and IntelliJ).
I also think the documentation in the Apple Developer Center website is well-written, and a good developer can get up and running quickly.
To more specifically answer your question, I haven't tried Unit Testing yet but I think the OOP is great - my domain objects in my iPhone apps are as robust and powerful as those I've written in Java.
I came out of college as Java developer. My first (real) job was Mac Development. Transitioning from a language I know (my starting point was Java) to something like Objective-C was fairly easy, code-wise. To maximize your time developing iPhone / Mac Applications, you have to make use of XCode and Interface Builder. Once you get the hang of attaching events and GUI outlets (the objects your UI want to communicate with), you'll be set for normal iPhone app development.
Here are the steps I went through learning Objective-C (the programming language for iPhone development) having my Java background:
Learn the basic OC object-oriented concepts. Subclassing (Inheritance), protocols (Java Interfaces), object properties (Bean properties), methods (you have to explicitly indicate the "parameter entry" labels, unlike in C / C++ / Java where you guess the parameter ordering).
Understand the difference between Objective-C, Cocoa, Aqua, and C. Then learn about how to use frameworks. Frameworks are pretty much the same as Java Packages.
Familiarize yourself with using these Foundation classes: NSString, NSArray, NSDictionary, NSSet, NSURL, NSAutoreleasePool.
Study more about Interface Builder. I thought before that the Visual Basic way of programming limits the programmer. I was wrong. It is better you "visualize" the app first before you get the hang of how things go in it. Take note about the keywords IBAction (analogous to making an EventListener), Outlets (you only have a few objects "exposed" for your UI elements), Views (UIView in case of the iPhone, everything that's "visible" in the application can be considered a "view"), and Controllers (there are ready-made controllers that you could use to populate Table Views, flip Card Views, etc.).
Learn how to deploy your app through the iPhone Developer Portal. You cannot send any iPhone app to any device if you don't have this "right". Yeah, I know it sucks, but you have to go through this process, anyway, if you want to sell your apps.
BTW, you could use the following for unit testing iPhone code: iPhone Unit Testing
Hope this one helps. :)
Objective-C is an object oriented language so, as far as OOP is concerned, pretty much anything you can do in Java you can do with Obj-C.
I don't have any experience with it but here's at least one resource on OCUnit, the objective-c equivalent to JUnit: http://developer.apple.com/tools/unittest.html
The biggest problem I'm having with the transition is definitely the memory-management aspect. Learning the syntax and APIs is pretty straight forward but life's tough without the GC!
EDIT: Oh yeah, the second biggest problem is XCode, the IDE used for Mac/iPhone development. Refactoring support is minimal and I find it a pain to navigate between files. Expect this to slow you down quite a bit, too.
For unit testing there are a few options, OCUnit was linked above. There is also google-toolbox-for-mac.
The OOP in objective-c is good, fairly clean. You will encounter old school C functions on occasion as well.
The API used is called Cocoa-Touch, and is built on Cocoa, which was built from NextStep, so there is a great history of design and refinements out there.
No garbage collection on the iPhone. The golden rule is "If you alloc, then you release". There are plenty of questions on SO regarding memory management, so I won't go into details here.
The major hurdle is the design / architecture differences. iPhone apps and java apps are build using different conventions. So consume as much objective-c / cocoa / cocoa-touch code as you can find / stand.
Spend some time working with Interface Builder, it can be aggravating, but that usually means your not understanding what its up to. Once you have a clear view of how IB works, and what it can do for you, you will really appreciate it.
Cocoadev.com is a handy resource for picking up design and code examples.
Cocoadevcentral.com has an excellent collection of articles, including desktop cocoa development. His learn objective-c article is one of the best you will find.
Get an Apple Developer Connection account if you don't have one yet. You don't have to pay for this one, but will get you into the documentation and tools.
ADC iPhone
iPhone Reference Library API Docs, guides, sample code, The official Apple stuff.
I wouldn't say that I'm an expert in any language but I'm competent in a few. Most of the code I've written recently has been "enterprise"-type stuff.
Assuming you're comfortable learning a new API and language, the biggest difference I found is how constrained the iPhone is in terms of CPU performance and available memory. I'm very used to trading off a bit of memory for better performance -- almost unconsciously -- or being a little wasteful because I've got eight cores at my disposal. That's a really bad idea on the iPhone!
The other hard thing is making sure that it's iPhone-y. Making a good app is not just a matter of shrinking the GUI down, you really need to think about presenting the data effectively.
The technical aspects are all pretty much sorted. The unit test side is less advanced than on the Java side. On the other hand I find that I can be much more productive and less error-prone in Objective C than Java, and this is probably due to the object model which is quite different (you tend to delegate rather than inherit).
Well, Java was based on Objective C and Smalltalk, which are object oriented languages. The big issues will be syntax (which is not entirely C based like C++ and Java), pointers and manual memory management.
This is based on some very old Objective C knowledge, but I do know that when I switched from Objective C to Java (around 2000), it was pretty easy since the underlying concepts were pretty close.
Based on Objective C
Memory management
It is worth mentioning that you can use C++ and C++ objects within your Objective-C code, often referred to as Objective-C++. This can be a valuable approach to separating your data model and other platform-independent code (written in standard C++) from your UI code (written in Objective-C using the Cocoa framework).
If you understand the idea of OOP through your Java experience, and if you have a basic idea of what pointers and memory management are, then the last obstacle in your way will be the alien syntax.
Syntax: I found this tutorial, among others, very clear and concise. In my mind, I conceptually mapped Objective-C and Java infrastructure, which you can do for the most part (i.e. a message is for the most part a method, a protocol is an interface, and so forth). Once you get over the initial shock, you will find that Objective-C development for UI applications can be rather intuitive and pleasant.
Structure: I don't program UI so much, so I found that I needed to get a better grasp of the MVC paradigm.
You may also find some cool language features, such as categories, that you wish you had in Java. I likewise find the lack of some other constructs, such as the lack of static members.