Multi-Modal Image Alignment Issue - c++

I am trying to align two multi-spectral images using multi-modal image registration techniques.
I built a prototype in MATLAB by first creating the optimizer and metric objects as follows:
[optimizer, metric] = imregconfig('Multimodal');
This creates an optimizer object of type OnePlusOneEvolutionaryOptimizer and metric of type MattesMutualInformation. The images are aligned as follows:
tform = imregtform(movingImage, fixedImage, 'rigid', optimizer, metric);
aligned = imwarp(movingImage,tform,'OutputView',imref2d(size(fixedImage)));
Then I went for a C++ implementation of the same algorithm which is offered by one of the examples in the ITK v4 library.
This example also gives correct results but here is the problem... The ITK version is way slower than the MATLAB version. I played around with the optimizer parameters and was able to speed it up a bit, but not comparable to MATLAB version.
MATLAB documentation of OnePlusOneEvolutionaryOptimizer states that the value of InitialRadius property is directly proportional to the algorithm's execution speed (compromising on robustness). The confusion here is that in ITK, the value of InitialRadius is inversely proportional to the execution speed as far as I tested.
I couldn't find literature/documentation describing how the optimizer parameters like InitialRadius and GrowthFactor are interpreted in ITK. Please help in providing explanation of these parameters and speeding up the algorithm.

The first thing to check is making sure you are compiling your program in Release mode, not Debug mode.
Documentation and source code for 1+1 optimizer in ITK are available online.

Related

Machine Vision - Hash An Image

I'm in the feasibility stage of a project and wanted to know whether the following was doable using Machine Vision:
If I wanted to see if two files were identical, I would use a hashing function of sorts (e.g. sha1 or md5) on the files and store the results in a database.
However, if I have two images where say image 1 is 90% quality and image 2 is 100% quality, then this will not work as they will have different hashes.
Using machine vision, is it possible to "look" at an image and create a signature from it, so that when another image is encountered, we can say "have we already got this image in the system", and if so, disregard the new image, and if not, save the image?
I know that you are able to perform Machine Vision comparison between two known images, e.g.:
https://www.pyimagesearch.com/2014/09/15/python-compare-two-images/
(there's a lot of code in there so I cannot simply paste in here for reference, unfortunately)
but an image by image comparison would be extremely expensive.
Thanks
python provide the module called : imagehash :
imagehash - encodes the image which is commend bellow.
from PIL import Image
import imagehash
hash = imagehash.average_hash(Image.open('./image_1.png'))
print(hash)
# d879f8f89b1bbf
otherhash = imagehash.average_hash(Image.open('./image_2.png'))
print(otherhash)
# ffff3720200ffff
print(hash == otherhash)
# False
print(hash)
above is the python code which will print "true" if images are identical and "false" if images are not identical.
Thanks.
I do not what you mean by 90% and 100%. Are they image compression quality using JPEG? Regardless of this, you can match images using many methods for example using image processing only approaches such as SIFT, SURF, BRISK, ORB, FREAK or machine learning approaches such as Siamese networks. However, they are heavy for simple computer to run (on my computer powered by core-i7 2670QM, from 100 to 2000 ms for a 2 mega pixel match), specially if you run them without parallelism ( programming without GPU, AVX, ...), specially the last one.
For hashing you may also use perceptual hash functions. They are widely used in finding cases of online copyright infringement as well as in digital forensics because of the ability to have a correlation between hashes so similar data can be found (for instance with a differing watermark) [1]. Also you can search copy move forgery and read papers around it and see how similar images could be found.

Caffe Batch processing no speedup

I would like to speedup the forward pass of classification of a CNN using caffe.
I have tried batch classification in Caffe using code provided in here:
Modifying the Caffe C++ prediction code for multiple inputs
This solution enables me to give a vector of Mat, but it does not speed up anything. Even though the input layer is modified.
I am processing pretty small images (3x64x64) on a powerful pc with two GTX1080, and there is no issue in terms of memory.
I tried also changing the deploy.prototxt, but I get the same result.
It seems that at one point the forward pass of the CNN becomes sequential.
I have seen someone pointing this out here also:
Batch processing mode in Caffe - no performance gains
Another similar thread, for python : batch size does not work for caffe with deploy.prototxt
I have seen some things about MemoryDataLayer, but I am not sure this will solve my problem.
So I am kind of lost on what to do exactly... does anyone have any information on how to speedup classification time.
Thanks for any help !

Is there a way to check the data in a matrix in opencv c++

I'm programming on Visual Studio c++ using OpenCV library for a project in Windows 7. I'm dealing with a lot of matrices of different types: uchar, float, double, Vec3d, Vec3b etc.
When I want to print out a value of an image, I stop the run, write the following line, cout << (int)mat.at<Veb3b>(i,j)[k];, and run from the beginning which is quite time consuming. In debug mode, I don't see the values of matrices, maybe the first index depending on the type. In Matlab, you can see the values, play with them on run time. (I'm fine with just seeing the values inside a matrix)
I'm wondering if there is a way to see the values on runtime using some external tool maybe. Many genius people have been working on OpenCV, some of them should have thought of it.
So, does anybody know about such a tool? I couldn't find anything related.
I'd recommend the Image Watch extension from Microsoft (link).
It has built-in support for OpenCV datatypes. Better for image data, though using it for regular matrices works well too. Can break at any point and view data in global or local variables and can even do some simple filtering on the data displayed. You can zoom in to view individual elements. Also supports exporting directly from the debugger.

Reduce a Caffe network model

I'd like to use Caffe to extract image features. However, it takes too long to process an image, so I'm looking for ways to optimize for speed.
One thing I noticed is that the network definition I'm using has four extra layers on top the one from which I'm reading a result (and there are no feedback signals, so they should be safe to delete).
I tried to delete them from the definition file but it had no effect at all. I guess I might need to remove the corresponding part of the file that contains pre-trained weights, too. That is, however, a binary file (a protobuffer) so editing it is not that easy.
Do you think that removing the four layers might have a profound effect of the net performance?
If so then how do I get familiar with the file contents so that I could edit it and how do I know which parts to remove?
first, I don't think removing the binary weights will have any effect.
Second, you can do it easily using the python interface: see this tutorial.
Last but not least, have you tried running caffe time to measure the performance of your net? this may help you identify the bottlenecks of your computations.
PS,
You might find this thread relevant as well.
Caffemodel stores data as key-value pair. Caffe only copies weight for those layers (in train.prototxt) having exactly same name as caffemodel. Hence I don't think removing binary weights will work. If you want to change network structure, just modify train.prototxt and deploy.txt.
If you insist to remove weights from binary file, follow this caffe example.
And to make sure you delete right part, this visualizing tool should help.
I would retrain on a smaller input size, change strides, etc. However if you want to reduce file size, I'd suggest quantizing the weights https://github.com/yuanyuanli85/CaffeModelCompression and then using something like lzma compression (xz for unix). We do this so we can deploy to mobile devices. 8 bit weights compress nicely.

OpenCV: findContours(); - What kernel am I using

Here is a fairly easy question, though I have a hard time answering my own question.
We are a group of five people, that have to write a report and we have to document everything we do etc. In our project, we uses the function 'findContours();' which is a function within the OpenCV library.
We know that the 'findContours();' function runs a Grass-Fire algorithm, though we need to document what kernel we are using, which we don't have a clue about.
The function we runs looks like this:
findContours( mGreenScale, vecContours, vecHierarchy, CV_RETR_CCOMP,
CV_CHAIN_APPROX_SIMPLE );
mGreenScale: Our binary image we run the function upon.
vecCountours: The vector handler that keep tracks on which pixel is a part of the contour.
vexHierarchy: We are not quiet sure what this is, though we think its some sort of array that handles the contour hierarchy, and keeps
track of what are edge contours and what are non-edge contours.
The two other inputs to the function is unknown to us, and we think its one of those two that defines the kernel we use.
I hope anybody is capable of identifying what kernel we are using.
Thanks in advance, pleas ask for further information if you feel I missed something out of importance.
circumstantial explanation:
We're a small group of not so experienced programmer, who have limited knowledge in C++ and just begun working with OpenCV a month ago. We have a limited time schedule, and a documentation that needs to be done within two weeks. We have already been looking through this exact site: OpenCV documentation though there are still terms we don't understand.
We don't have the necessary time to check through the source code nor the experience to do so.
We think it is a grass-fire algorithm, as we know no other algorithm capable of detecting BLOBS.
What each parameter is doing is clearly explained in the OpenCV documentation
And you can find the kernel looking into the OpenCV code. It's open-source. But I am not sure if it used any kernel at all. How do you know about the algorithm if you did not check the source?