I'm writing a Gaussian blur with variable radius (standard deviation), i.e. each pixel of the image is convolved using a different kernel. The standard techniques to compute Gaussian blur don't work here: FFT, axis-separation, repeated box-blur—they all assume that the kernel is the same for the whole image.
Now, I'm trying to approximate it using the following scheme:
Approximate the Gaussian kernel K(x,y) with a piecewise constant function f(x,y) defined by a set N of axis-aligned rectangles Rk and coefficients αk as:
f(x,y) = ∑k=1N αk·χRk(x,y)
Let g(x,y) be our image, then
∬ℝ2 K(x,y)·g(x,y) dxdy ≈
∬ℝ2 f(x,y)·g(x,y) dxdy = ∑k=1N αk·∬Rkg(x,y) dxdy
The integral on the RHS is a simple integral over a rectangle, and as such can be computed in constant time by precomputing the partial sums for the whole image.
The resulting algorithm runs in O(W·H·N) where W and H are the dimensions of the image and N is (AFAIK) inverse proportional to the error of the the approximation.
The remaining part is to find a good approximation function f(x,y). How to find the optimal approximation to the Gaussian when given either the number of rectangles N (minimizing the error) or given the error (minimizing the number of rectangles)?
Given the locations and size of the rectangles, it should be fairly easy to work out your coefficients, so the real problem is working out where to put the rectangles.
Since you are approximating a Gaussian, it seems at least reasonable to restrict our attention to rectangles whose centre coincides with the centre of the Gaussian, so we actually have only a 1-dimensional problem - working out the sizes of a nested set of rectangles which I presume are either squares or are similar to the Gaussian if you have an aspect ratio other than unity.
This can be solved via dynamic programming. Suppose that you work from the outside into the middle. At stage N you have worked out an n x k table that gives you the best possible approximation error coming from 1,2...N rings of outer pixels for up 1,2,..k different rectangles, and the size of the innermost rectangle responsible for that best error. To work out stage N+1 you consider every possible size for what will be an innermost rectangle so far, contributing x rings of pixels to the outer area. You work out the alpha for that rectangle that gives the best fit for the pixels in the new ring and the rings outside it not left to outer rectangles. Using the values in the table already calculated you know the best possible error you will get when you leave up to k outer rectangles to cover those areas, so you can work out the best total error contributed from what is now N+1 rings of pixels. This allows you to fill in the table entries for N+1 outer pixels. When you have worked your way into the middle of the area you will be able to work out the optimal solution for the whole area.
Related
Given an array of 3D integers, what is the algorithmic complexity of determining which of those integers exist within a cube? I'm assuming the points can be represented in a number of concurrent data structures, each sorted in one or more dimensions.
My intuition tells me given a sorted array of points in 1D one can determine the subset of points between some lower and upper bound in something like O(log(n), but I would be very grateful for any insights others can offer on this notion (and any help others can offer generalizing to the multidimensional case!).
If you're unfamiliar with the math involved, I recommend doing this problem in two dimensions first, with a rectangle. That way, you can get familiar with the math, which is really just a bit of basic trigonometry. After that, stepping up to three dimensions isn't very difficult.
The problem is much simpler if the cube (or rectangle) is axis aligned, so you probably should do that first. For an example of determining the rotation you need, see How to calculate rotation angle from rectangle points?.
Once you've determined the rotation angle, you can translate the rectangle to the origin and rotate it by doing the first two steps in the accepted answer here: Drawing a Rotated Rectangle.
You now have an axis-aligned rectangle that's centered at the origin.
Finally, for each of your points:
Apply the same translation and rotation that you applied to the rectangle.
Test to see if the x and y coordinates in the resulting point are within the rectangle. This is a matter of, at most, four bounds checks.
If the point is in the rectangle, save it.
Once you've done this in two dimensions, you should be able to apply those concepts to three dimensions.
The algorithm is O(n), where n is the number of points.
I am interesting in finding the diameter of two points sets, in 128 dimensions. The first has 10000 points and the second 1000000. For that reason I would like to do something better than the naive approach which takes O(n²). The algorithm will be able to handle any number of points and dimensions, but I am currently very interested in these two particular data sets.
I am very interesting in gaining speed over accuracy, thus, based on this, I would find the (approximate) bounding box of the point set, by computing the min and max value per coordinate, thus O(n*d) time. Then, if I find the diameter of this box, the problem is solved.
In the 3d case, I could find the diameter of the one side, since I know the two edges and then, I could apply the Pythagorean theorem on the other, which is vertical to this side. I am not sure for this however and for sure, I can't see how to generalize it to d dimensions.
An interesting answer can be found here, but it seems to be specific for 3 dimensions and I want a method for d dimensions.
Interesting paper: On computing the diameter of a point set in high dimensional Euclidean space. Link. However, implementing the algorithm seems too much for me in this phase.
The classic 2-approximation algorithm for this problem, with running time O(nd), is to choose an arbitrary point and then return the maximum distance to another point. The diameter is no smaller than this value and no larger than twice this value.
I would like to add a comment, but not enough reputation for that...
I just want to warn other readers that the "bounding box" solution is very inaccurate. Take for example the Euclidean ball of radius one. This set has diameter two, but its bounding box is [-1, 1]^d, which has diameter twice the square root of d. For d = 128, this is already a very bad approximation.
For a crude estimate, I would stay with David Eisenstat's answer.
There is a precision based algorithm which performs very well on any dimension, which is based on computing the dimension of an axial bounding box.
The idea is that it's possible to find the lower and upper boundaries of the axis bounding box length function since it's partial derivatives are limited, and depend on the angle between the axises.
The limit of the local maxima derivatives between two axises in 2d space can be computed as:
sin(a/2)*(1 + tan(a/2))
That means that, for example, for 90deg between axises the boundary is 1.42 (sqrt(2))
Which reduces to a/2 when a => 0, so the upper boundary is proportional to the angle.
For a multidimensional case the formula varies slightly, but still it's easy to compute.
So, the search of local minima convolves in logarithmic time.
The good news is that we can run the search of such local maxima in parallel.
Also, we can filter out both the regions of the search based on the best achieved result so far, as well as the points themselves, which are belo the lower limit of the search in the worst region.
The worst case of the algorithm is where all of the points are placed on the surface of a sphere.
This can be firther improved: when we detect a local search which operates on just few points, we swap to bruteforce for this particular axis. It works fast, because we need only the points which are subject to that particular local search, which can be determined as points actually bound by two opposite spherical cones of a particular angle sharing the same axis.
It's hard to figure out the big O notation, because it depends on desired precision and the distribution of points (bad when most of the points are on a sphere's surface).
The algorithm i use is here:
Set the initial angle a = pi/2.
Take one axis for each dimension. The angle and the axises form the initial 'bucket'
For each axis, compute the span on that axis by projecting all the points onto the axis, and finding min and max of the coordinates on the axis.
Compute the upper and lower bounds of the diameter which is interesting. It's based on the formula: sin(a/2)*(1 + tan(a/2)) and multiplied by assimetry cooficient, computed from the length of the current axis projections.
For the next step, kill all of the points which fall under the lower bound in each dimension at the same time.
For each exis, If the amount of points above the upper bound is less then some reasonable amount (experimentally computed) then compute using a bruteforce (N^2) on the set of the points in question, and adjust the lower bound, and kill the axis for the next step.
For the next step, Kill all of the axises, which have all of their points under the lower bound.
If the precision is satisfactory (upper bound - lower bound) < epsilon, then return the upper bound as the result.
For all of the survived axises, there is a virtual cone on that axis (actually, the two opposite cones), which covers some area on a virtual sphere which encloses a face of the cube. If i'm not mistaken, it's angle would be a * sqrt(2). Set the new angle to a / sqrt(2). Create a whole bucket of new axises (2 * number of dimensions), so the new cone areas would cover the initial cone area. It's the hard part for me, as i have not enough imagination for n>3-dimensional case.
Continue from step (3).
You can paralellize the procedure, synchronizing the limits computed so far for the points from (5) through (7).
I'm going to summarize the algorithm proposed by Timothy Shields.
Pick random point x.
Pick point y furthest from x.
If not done, let x = y, and go to step 2
The more times you repeat, the more accurate the result will be... ??
EDIT: actually this algorithm is not very good. Think about a 2D rectangle with vertices ABCD. There are two maxima: between AC and BD, which are separated by a sizable valley. This algorithm will get stuck at one or the other 50/50. If AC is slightly larger than BD, you'll be getting the wrong answer 50% of the time no matter how many times you iterate. Other regular polygons have the same issue, and in higher dimensions it is even worse.
I am trying to figure out whether given those constraints regular 2D packing problem can be simplified. You have n regular s-sided polygons for s between 3 and 12. All of them have the same side length. We need to minimise the area of bounding square.
I would think that having all of the regular with same side length the packing can be easier since some configurations will always fit perfectly next to each other. Though I am not sure whether this property is of any use since local minimum might not translate to global minimum.
From your description, the polygons are regular polygons with all sides having the same length
This means that every polygon edges can connect to form a circle which can fit into a sub-square of size of 2r^2 perfectly
So an easy solution is to fit N polygons aligned in a square of size >= N * 2r^2, this is not an optimal solution, but works perfectly when you only have squares.
Here is an illustration that explains it:
First, knowing that all polygon sides have length of m
The polygon fits perfectly into a circle of ratio r
That circle fits perfectly into a square of size 2r^2
So we finally merge the fitting squares into one big square by tiling them in a matrix of M x M squares, where M * M >= N
I am new to matlab, so forgive me if i am asking for the obvious here: what i have is a collection of color photographic images (all the same dimensions). What i want to do is calculate the median color value for each pixel.
I know there is a median filter in matlab, but as far as i know it does not do exactly what i want. Because i want to calculate the median value between the entire collection of images, for each separate pixel.
So for example, if i have three images, i want matlab to calculate (for each pixel) which colorvalue out of those three images is the median value. How would i go about doing this, does anyone know?
Edit: From what i can come up with, i would have to load all the images into a single matrix. The matrix would have to have 4 dimensions (height, width, rgb, images), and for each pixel and each color find the median in the 4th dimension (between the images).
Is that correct (and possible)? And how can i do this?
Your intuition is correct. If you have images image_1, image_2, image_3, for example, you can assign them to a 4 dimensional matrix:
X(:,:,:,1) = image_1;
X(:,:,:,2) = image_2;
X(:,:,:,3) = image_3;
Then use:
Y=median(X,4);
To get the median.
Expanding my comments into a full answer;
#prototoast's answer is elegant, but since medians for the R, G and B values of each pixel are calculated separately, the output image will look very strange.
To get a well-defined median that makes visual sense, the easiest thing to do is cast the images to black-and-white before you try to take the median.
rgb2gray() from the Image Processing toolbox will do this in a way that preserves the luminance of each pixel while discarding the hue and saturation.
EDIT:
If you want to define the "RGB median" as "the middle value in cartesian coordinates" this is easy enough to do for three images.
Consider a single pixel with three possible choices for the median colour, C1=(r1,g1,b1), C2=(r2,g2,b2), C3=(r3,g3,b3). Generally these form a triangle in 3D space.
Take the Pythagorean distance between the three colours: D1_2=abs(C2-C1), D2_3=abs(C3-C2), D1_3=abs(C3-C1).
Pick the "median" to be the colour that has lowest distance to the other two. Defining D1=D1_2+D1_3, etc. and taking min(D1,D2,D3) should work, courtesy of the Triangle Inequality. Note the degenerate cases: equilateral triangle (C1, C2, C3 equidistant), line (C1, C2, C3 linear with each other), or point (C1=C2=C3).
Note that this simple way of thinking about a 3D median is hard to extend to more than three images, because "the median" of a set of four or more 3D points is a bit harder to define.
Edit 2
For defining the "median" of N points as the centre of the smallest sphere that encloses them in 3D space, you could try:
Find the two points N1 and N2 in {N} that are furthest apart. The distance between N1 and N2 is the diameter of the smallest sphere that encloses all the points. (Proof: Any smaller and the sphere would not be able to enclose both N1 and N2 at the same time.)
The median is then halfway between N1 and N2: M = (N1+N2)/2.
Edit 3: The above only works if no three points are equidistant. Maybe you need to ask math.stackexchange.com?
Edit 4: Wikipedia delivers again! Smallest circle problem, Bounding sphere.
Is there any algorithm to find a distribution of area into n sub-regions, where each sub-region might have different area.
To formally put the problem statement: Suppose you have a rectangular plot. How will you divide the region into n rectangles. The sum of area of these sub-rectangles will be equal to original rectangular plot(So there wouldn't be any overlaps between the rectangles)
And the area of each of these smaller n rectangles is given before hand.
Restriction is on width of each sub-rectangle.
This subdivision has to be displayed on may be a computer screen which is divided into pixels. So I don't want any areas any dimension to be smaller than a pixel(or maybe 10), which might be of no use to display as such.
I was looking at a rectangle packing algorithm here but this seems to be wasting space which I don't want. Does there exist any algorithm to solve this problem.
Backtracking doesn't seem to be a good solution in this case as the sub-rectangles area is only specified, not the dimensions, or is it?
Example 1:
Example 2:
The integral of a function is the area bound by the limits, the curve of the function, and the x-axis. Define one side of the rectangle as the x-axis, then find the boundaries for the others. There are plenty of numerical integration libraries around in the language of your choice.
EDIT: some difficulties in trying to illustrate in words...
Assuming, at least, that the containing rectangle has an area larger than the sum of the areas of the sub-regions; and there is no requirement of a certain order of containment:
Contain the largest sub-region first with edges on the axes.
Pick the next smaller sub-region.
Create the function (integral) to calculate the free area as seen from each axes.
With windows/limits equal to the length on the sub-region's sides (facing the axes), slide these windows along the axes away from the origin.
Create the function for finding the free space bounded by the outside arms of the cross formed by the windows as they slide along the axes. Efficiency in the use of space is found in the region where free space is minimal (differentiation).
Rotate the sub-region by 90 degrees and repeat from step 3.
Place the sub-region in the orientation and location where most efficient.
Repeat step 2. Stop when sliding windows report negative
free space for the entire domain (allocated space overlaps the placeholder made by the windows).
In theory, this will systematically try to squeeze in sub-regions. Sketch and pseudocode to follow if time permits.