Image 8-connectivity without excessive branching? - performance

I'm writing a low level image processing algorithm which needs to do alot of 8-connectivity checks for pixels. For every pixel I often need to check the pixels above it, below it and on its sides and diagonals.
On the edges of the image there are special cases where there are only 5 or 3 neighbors instead of 8 neighbors for a pixels. The naive way to do it is for every access to check if the coordinates are in the right range and if not, return some default value.
I'm looking for a way to avoid all these checks since they introduce a large overhead to the algorithm. Are there any tricks to avoid it altogether?

For performance-critical code you might do something like the following:
process row 0
for r = 1 to M - 2
process row r, pixel 0
for c = 1 to N - 2
process row r, pixel c
process row r, pixel N - 1
process row M - 1
The bulk of the operations are in the inner loop and are branchless. You just handle the first/last row, and the first/last pixel of each row, as special cases. It makes the code bulkier, but that's the nature of the beast when it comes to optimisation.

If there are suitable values for your algorithm, add a 1-pixel border and only check your original pixel data.

Or, to turn #Roger's suggestion around, ignore the outermost pixel along each border, if this works for you. In other words, only process the interior pixels of your image.

Related

Different methods to normalize images

I want to normalize images whose pixel can have negative values and found two different ways to do that. Given a two-dimensional matrix X I can do the following:
a) X = 0.5*((X/max(abs(X))+1)
b) X = (X-min(X))/(max(X)-min(X))
Since I'm not an expert, I'm not sure which of the two is the more useful way to normalize images. Does one of the two options have certain advantages?
For GLCM is does not at all matter where the 0 level is, what matters is the differences between intensities. Thus, I would pick the method that linearly stretches between the min and max intensity. This method uses the output range best, and therefore introduced the least quantization error.
When comparing GLCM results across images, it is best if all images are stretched the same way. I would select a global min and max, keep those constant for all images in the set.
Note that for other purposes, the answer will be different.
The second approach will use the full range between 0 and 1, which may be what you want. The first approach will map 0 always to 0.5. When the data is symmetrically spread around 0, also the first approach will use the full range between 0 and 1.
Up to you to decide what you want.

Showing two images with the same colorbar in log

I have two sparse matrices "Matrix1" and "Matrix2" of the same size p x n.
By sparse matrix I mean that it contains a lot of exactly zero elements.
I want to show the two matrices under the same colormap and a unique colorbar. Doing this in MATLAB is straightforward:
bottom = min(min(min(Matrix1)),min(min(Matrix2)));
top = max(max(max(Matrix1)),max(max(Matrix2)));
subplot(1,2,1)
imagesc(Matrix1)
colormap(gray)
caxis manual
caxis([bottom top]);
subplot(1,2,2)
imagesc(Matrix2)
colormap(gray)
caxis manual
caxis([bottom top]);
colorbar;
My problem:
In fact, when I show the matrix using imagesc(Matrix), it can ignore the noises (or backgrounds) that always appear with using imagesc(10*log10(Matrix)).
That is why, I want to show the 10*log10 of the matrices. But in this case, the minimum value will be -Inf since the matrices are sparse. In this case caxis will give an error because bottom is equal to -Inf.
What do you suggest me? How can I modify the above code?
Any help will be very appreciated!
A very important point is that the minimum value in your matrix will always be 0. Leveraging this, a very simple way to address your problem is to add 1 inside the log operation so that values that map to 0 in the original matrix also map to 0 in the log operation. This avoids the -Inf error that you're encountering. In fact, this is a very common way of visualizing the Fourier Transform if you will. Adding 1 to the logarithm ensures that the transform has no negative values in the output, yet the derivative or its rate of change remains intact as the effect is simply a translation of the curve by 1 unit to the left.
Therefore, simply do imagesc(10*log10(1 + Matrix));, then the minimum is always bounded at 0 while the maximum is unbounded but subject to the largest value that is seen in Matrix.

Algorithm - Grid Map find number of sub-blocks with specific property

I have a grid map NxN. Each cell may have the value '0' or '1'. I am trying to find the exact number of distinct rectangle sub-blocks of the map that include a specific number of '1' and this number can be between 1 and 6. I have thought of searching for each possible rectangle but this is very slow for a map of size 500x500 and the solution must be ~ 1 sec for a common desktop computer. Can someone tell me a corresponding problem so I can look for a working algorithm or better can someone suggest me a working algorithm for this problem? Thank you all in advance!
I imagine that your search of all the rectangles is slow because you are actually counting on each possible rectangle. The solution to this is not to count all rectangles, but rather create a second array of NxN which contains the count for the rectangle (0,0..x,y), call this OriginCount. Then to calculate the count for any given rectangle, you will not have to go through the rectangle and count. You can simply use
Count(a,b..c,d) = OriginCount(c,d) + OriginCount(a-1,b-1) -
OriginCount(a-1,d) - OriginCount(c,b-1)
That turns the problem of counting the ones in any given rectangle, from an N2 problem to a discrete or constant time problem, and your code gets in the order of thousands times faster (for your 500x500 case)
Mind you, in order to set up the OriginCount array, you can use the same concept, don't just go count the ones for each rectangle, from 0,0 to x,y. Rather, use the formula
OriginCount(x,y) = OriginCount(x-1,y) + OriginCount(x,y-1) - OriginCount(x-1,y-1) +
GridMap(x,y) == 1 ? 1 : 0;
Mind you, you have to account for edge cases - where x=0 or y=0.

Implementing the intelligent recursive algorithm in matlab

Well am referring the following paper and trying to implement the algorithm as given in matlab
The only problem is how do i find a noisy pixel i.e Pixel with impulse noise?
X seems to be the impulse pixel in an image which i have to calculate
_
____________________________________________
Input – Noisy Image h
_______________________________________________
Step 1: Compute X
for every pixel repeat steps from 2 to 7
Step 2: Initialize w = 3
Step 3: If X(i,j) ≠ Impulse pixel
goto step 7
Step 4: ∆i,j = { h(i1,j1) | i-(w-1)/2 ≤ i1 ≤ i+(w-1)/2,
j-(w-1)/2 ≤ j1 ≤ j+(w-1)/2}
b=no. of black pixels in the window
w=no. of white pixels in the window
Step 5: If ∆i,j ≠ NULL
p(i,j) = mean(∆i,j
)
d(i,j) = | h(i,j) – p(i,j) |
else if (w < wmax)
w=w+2
goto step 4
else
if (b>w)
h(i,j)=0
else
h(i,j)=255
Step 7: Goto next pixel
Step 8: Calculate threshold t, from detailed coefficient
matrix d
for every pixel
Step 9: If (d(i,j)>t)
h(i,j)=p(i,j)
____________________________
Edit: To implement the PSM or the median filter method we
need to set some parameters and a threshold value. This
threshold value is dependent on the image and the noise
density. So, to restore different images we need to check for
a range of threshold values and find out the best one. So, in
our proposed algorithm we removed the need to define a threshold value. The algorithm is intelligent and determines
the threshold automatically.
The article you are trying to implement is obviously badly written...
For instance in the algorithm w means 2 things: the size of the window, and the number of white pixels!!!
Both the step 1 and 7, are refering to the same loop.
Anyway, to me, the "impulse pixels" are all the pixels a which are either equal to 0 or 255.
Basically, they are the pixels which are part of the "salt and pepper" noise.
So basically, you can find them by doing:
[impulsepixelsY,impulasPixelX]=find((im==0)|(im==255));
From the paper it seems that the "impulse pixels" are just the noisy pixels, in the case of salt & pepper noise. Furthermore, it also seems that the algorithm provides an "intelligent" mechanism to calculate the denoised value of a noisy pixel if its value is above a threshold (which it calculates adaptively).
So, what about "If X(i,j) ≠ Impulse pixel " ? Well, apparently, the authors assume to know (!) which pixels are noisy (!!), which makes the whole thing rather ridiculous, since this info is almost impossible to know.
I might also add that the rather stunning results presented in the paper are most probably due to this fact.
P.S. Regarding the argument that <"impulse pixels" are all the pixels a which are either equal to 0 or 255>, it is wrong. The set of pixels that have either 0 or 255 intensity value, includes the noisy pixels as well as proper pixels that just happen to have such a value. In this case, the algorithm will most probably collapse since it will denoise healthy pixels as well.

Finding image subsets between two images

I'm working on a way to handle hardware-based bitmap animation. As an input, I've got an image sequence of a simple bitmap (it's not a video, it's more like simple shapes, even though they might contain bitmap fills). I'm making a texture atlas of this animation (so it can be rendered quickly with GPU), and since this sequence sometimes has most part of it standing still while a small part of it is animating, I need an algorithm that can find the "common parts" between two images, so I can save memory.
The images might not have the same size (if an object is growing or shrinking, for example), so I need a way to detect the biggest common area between the two. I've seen this answer and it partly solves my problem. I'd like to know, though, if there is already a better algorithm for my case, specially because since the sizes can vary, one image is not necessarily contained within the other, but I'd need to find the common parts between the two.
One problem I see is that one image can be contained in many ways in another, how do you determine the right answer?
Does it have to be real-time? If not then you can do the simple O(n^4) search for it using a fitness function.
The fitness function could be the error between the images (which gives a n^8 algorithm).
UPDATE:
Wrong analysis of me sorry. The search is n^2 and the fitness function is n^2 which gives n^4.
The whole algorithm should look something like this:
w1 = width of image 1
w2 = width of image 2
h1 = height of image 1
h2 = height of image 2
for x = -w1 to w1+w2
for y = -h1 to h1+h2
find max fitness(x,y)
fitness(xc,yc){
m=0
for each x where image 1 overlaps image 2 displaced by xc
for each y where image 1 overlaps image 2 displaced by yc
if (image1[x][y] == image2[x+xc][y+yc])
m += 1
return m
}
UPDATE: Modified fitness function to find the number of overlaps, and then try to find the most overlaps.

Resources