itk::NeighborhoodIterator python wrapping - python

I'm using ITK python wrapper (ITK not simpleITK) to prototype µCT output automated processing. I need to compute 3D object thickness map, but this feature doesn't exist as-is in ITK. The pipeline is simple:
Binarize the object
Compute the distance transform
Extract the medial axis as the distance map local-max
My problem is that the itk::RegionalMaximaImageFilter does not behave as expected (does not preserve branches). So I wanted to write a custom function that check if the central pixel is >= to its neigborhood with a 3x3x3 sliding kernel.
My idea is to take advantage of the optimized itk::RegionalMaximaImageFilter iterator (see here). However, even if this works perfectly with C++, I can't manage to find a workaround with Python (without wrapping c code with cython).

Python wrapping is not meant to access iterators, but rather invoke existing classes. What you can do is write a class in C++, and follow this to create a module which can be wrapped and used from Python.

" I wanted to write a custom function that check if the central pixel is >= to its neigborhood with a 3x3x3 sliding kernel."
This is related to gray-scale morphology's dilate which is the maximum of all the pixels in a neighborhood. In SimpleITK ( since you tagged the post ) you could simply write:
isMaximumImg = (sitk.GrayscaleDilateImageFilter(inImg, 1) == inImg)
This will result in an image where if the pixel is equal to the maximum in the neighborhood, then the output value is 1, otherwise it would be 0. This should also be able to be implemented with ITK Python by composing a similar pipeline of Filters.

Related

Alternative to opencv warpPerspective

I am using opencv warpPerspective() function to warp the found countour in the image to find contour i am using findContours().
This is shown in this image:
but the warpPerspective() function takes "more time" to warp to full image is there any alternative to this function to warp the object in image to full image as shown in figure.
OR will traversing help?but this would be difficult to do so that i can reduce the time the warpPerspective() function takes.
You can try to work on rotation and translation matrices (or roto-translational matrix, a combination of both), which can warp image as you wish. The function warpPerspective() utilizes similar approach, so you will basically will have an opportunity to look inside the function.
The approach is:
You calculate the matrix, then multiply the height and width of
the original image to find dimensions of the output image.
Go through all pixels in the original image and multiply their
(x,y) coordinates to the matrix R
(rotation/translation/roto-translation matrix) to get the
coordinates on the output image (xo,yo).
On every calculated coordinate (xo,yo) assign value from the
corresponding original image coordinate (x,y).
Interpolate using median filter/bilinear/bicubic/etc. method as
sometimes there may be empty points left on the output image
However, if you work in Python your implementation may work even slower than warpPerspective(), so you may consider C++. Another thing is that OpenCV uses C++ compiler and I am pretty sure that implementation of warpPerspective() in OpenCV is very efficient.
So, I think that you can go around warpPerspective(), however, I am not sure if you can do it faster than in OpenCV without any boosts (like GPU, powerful CPU etc.) :)
Good luck!

How to detect turtle objects intersecting in python?

I'm using turtle and inserting 2 shapes into the program and I am trying to make the program perform a specific function when the objects intersect. Is it possible to do it with an if statement?
I suspect that the proper answer is "no". Turtle graphics does not maintain the shape in a form useful for you to test, nor does it provide shape manipulation methods.
You could develop your own package to represent objects, and include an intersection method, but this takes a lot of work. If you're interested, see the BOOST library shape methods (that's in C++) that Luke Simonson did (2009, I think).
However, if your shapes are regular enough, you can make a proximity detector. For instance, if the shapes are more or less circular, you could simply see whether they've come within r1 + r2 of each other (a simple distance function on their current positions), where r1 & r2 are the radii of the objects. Is that close enough for your purposes?

Converting these Matlab functions to Python cv2?

I've been asked to convert some older Matlab code (which we no longer have a license) to Python using the opencv (cv2) library. This all has to do with SURF operations generating points and descriptors in order to eventually mosaic two images together using gdal.
The two functions are:
points = points.selectStrongest(50000);
T = estimateGeometricTransform(points1, points2, 'affine','MaxDistance',0.5);
These: selectStrongest() & estimateGeometricTransform()
Other parts I have already figured out are dealing with reading images with imread(), setting up the SURF object, and gathering points and descriptors using detectAndCompute(), but I'm guessing that I need to first select the "strongest" points before computing descriptors.
Please let me know if there is anything else I can add to clear this up. Essentially, I just don't know the python equivalent to those two functions. Perhaps it's a series of python/cv2 functions that would be necessary to recreate these?

Efficient way to handle boundary pixels when implementing arbitrary image algorithms in Python

Image processing algorithms often require pixel values within a neighborhood of individual image locations. However, the neighborhood for boundary points is incomplete and needs special handling with various methods, e.g., mirror-reflecting, periodic, etc.
For linear operation, an efficient way is to turn the algorithm into a kernel and do 2D convolution. The convolution routine usual has boundary handling methods built in.
For arbitrary (non-linear) algorithms, one possibility is to pad the image first, gather all neighborhoods at once (e.g., with pad+neighbor), and do your operation in a vectorized way. However, this can be memory heavy as the doc suggested.
Loop through pixels and handle boundaries case by case is another way. But this can be slow in Python (though feasible in C/C++), and to provide all this mirror/periodic stuff seems to be cumbersome...
How to do this efficiently (and perhaps Pythonic) when implementing you own algorithms in Python?
And is there some function that returns the neighborhood of a specified pixel, and with specified boundary handling method?
The most pythonic and efficient way to do handle boundary conditions during image processing would be to use an existing library. On top of PIL and ImageMagick, I would also recommend OpenCV.
By itself, Python doesn't provide any image processing functions, so any questions about the neighborhood of a specific pixel are library-specific. Pick a library that you like and play around with it - if you can't work out how that library handles boundary conditions, come back and ask again.
PIL is one of the best known libraries to handle image processing. You might also want to take a look at ImageMagick, which i think has lots of cool image transformation features inbuilt.

Detect the location of an image within a larger image

How do you detect the location of an image within a larger image? I have an unmodified copy of the image. This image is then changed to an arbitrary resolution and placed randomly within a much larger image which is of an arbitrary size. No other transformations are conducted on the resulting image. Python code would be ideal, and it would probably require libgd. If you know of a good approach to this problem you'll get a +1.
There is a quick and dirty solution, and that's simply sliding a window over the target image and computing some measure of similarity at each location, then picking the location with the highest similarity. Then you compare the similarity to a threshold, if the score is above the threshold, you conclude the image is there and that's the location; if the score is below the threshold, then the image isn't there.
As a similarity measure, you can use normalized correlation or sum of squared differences (aka L2 norm). As people mentioned, this will not deal with scale changes. So you also rescale your original image multiple times and repeat the process above with each scaled version. Depending on the size of your input image and the range of possible scales, this may be good enough, and it's easy to implement.
A proper solution is to use affine invariants. Try looking up "wide-baseline stereo matching", people looked at that problem in that context. The methods that are used are generally something like this:
Preprocessing of the original image
Run an "interest point detector". This will find a few points in the image which are easily localizable, e.g. corners. There are many detectors, a detector called "harris-affine" works well and is pretty popular (so implementations probably exist). Another option is to use the Difference-of-Gaussians (DoG) detector, it was developed for SIFT and works well too.
At each interest point, extract a small sub-image (e.g. 30x30 pixels)
For each sub-image, compute a "descriptor", some representation of the image content in that window. Again, many descriptors exist. Things to look at are how well the descriptor describes the image content (you want two descriptors to match only if they are similar) and how invariant it is (you want it to be the same even after scaling). In your case, I'd recommend using SIFT. It is not as invariant as some other descriptors, but can cope with scale well, and in your case scale is the only thing that changes.
At the end of this stage, you will have a set of descriptors.
Testing (with the new test image).
First, you run the same interest point detector as in step 1 and get a set of interest points. You compute the same descriptor for each point, as above. Now you have a set of descriptors for the target image as well.
Next, you look for matches. Ideally, to each descriptor from your original image, there will be some pretty similar descriptor in the target image. (Since the target image is larger, there will also be "leftover" descriptors, i.e. points that don't correspond to anything in the original image.) So if enough of the original descriptors match with enough similarity, then you know the target is there. Moreover, since the descriptors are location-specific, you will also know where in the target image the original image is.
You probably want cross-correlation. (Autocorrelation is correlating a signal with itself; cross correlating is correlating two different signals.)
What correlation does for you, over simply checking for exact matches, is that it will tell you where the best matches are, and how good they are. Flip side is that, for a 2-D picture, it's something like O(N^3), and it's not that simple an algorithm. But it's magic once you get it to work.
EDIT: Aargh, you specified an arbitrary resize. That's going to break any correlation-based algorithm. Sorry, you're outside my experience now and SO won't let me delete this answer.
http://en.wikipedia.org/wiki/Autocorrelation is my first instinct.
Take a look at Scale-Invariant Feature Transforms; there are many different flavors that may be more or less tailored to the type of images you happen to be working with.

Categories