How to select bottom half of picture? - jes

def changeRed():
setMediaPath("/Users/addison/Downloads/Cmpt101_Pics/Learjet31A.jpg")
filename1 = "/Users/addison/Downloads/Cmpt101_Pics/Learjet31A.jpg"
source = makePicture(filename1)
halfHeight = getHeight(source)/2
for x in range(0,getWidth(source)):
for y in range(0, halfHeight):
pixel = getPixel(source, x, y)
value = getRed(pixel)
setRed(pixel, value-127.5)
show(source)
Sooo this is my code right now to select the top half of a picture and decresa the redness by 50%. My program also needs to select the bottom half of the picture and increase the redness by 50%, how do i go about doing this?

Pretty much add another for loop within the x in range loop but not in the for y loop you already have. This new for y in range loop should have a range of halfHeight,getHeight(source). Also subtracting -127.5 from red pixels isnt decreasing the red by 50%. Use value/2 instead.

Related

how to stretch the first left, right, top, and bottom row/column of image?

I have a satellite image and I want to show an example of multi-scale.
so what I did is, add zeros (black pixels) around the image and put the image in the centre. now how can I fill the zeros from the first left, right, top, and bottom pixel row/column?
Matlab code:
img=imread ('example.jpg');
padcam = padarray(img,[1000 1000],'both');
EDIT:
Maybe it is easy explain from this image. Is this image what I want is to repeat the sea part in such a ways at the black area that it looks like we have large empty sea and small ships at the centre. That's why I have made red lines that I want to repeat/make copy/extend first left, right, top, and bottom pixel row/column so that make image at centre and black will be converted to pixels values of first left, right, top, and bottom pixel row/column.
I don't know if this is what you have meant...
Instead of fill zeros, start from the highest resolution, and place lower resolution images at the center of each other.
Here is my code sample (you may use a for loop instead):
I0 = imread('peppers.png');
I0 = padarray(I0,[16 16],'both'); %I0 - full resolution.
I1 = imresize(I0, 0.5); %I1 - half resolution.
I2 = imresize(I0, 0.25); %I2 - quarter resolution.
J = I0;
%Place I1 at the center of J.
J(1+(end-size(I1,1))/2:(end+size(I1,1))/2, 1+(end-size(I1,2))/2:(end+size(I1,2))/2, :) = I1;
%Place I2 at the center of J.
J(1+(end-size(I2,1))/2:(end+size(I2,1))/2, 1+(end-size(I2,2))/2:(end+size(I2,2))/2, :) = I2;
figure;imshow(J);
Result:
Check the following:
The example is basted on Matlab documentation of imtransform
I = imresize(imread('peppers.png'), 0.5);
A = [1, 0, 0; 0, 1, 0; 0, 0, 1];
T = maketform('affine', A);
R = makeresampler({'cubic', 'nearest'}, 'replicate');
J = imtransform(I, T, R, 'XData', [-size(I,2), size(I,2)*2], 'YData', [-size(I,1), size(I,1)*2]);
figure;imshow(J);
Result:
I think you are looking for 'replicate' padding option:
padcam = padarray(img,[1000 1000],'both', 'replicate');
resulting with:
If you are looking for smoother result, consider using regionfill.

maximum intensity projection matlab with color

Hi all I have a stack of images of fluorescent labeled particles that are moving through time. The imagestack is gray scaled.
I computed a maximum intensity projection by taking the maximum of the image stack in the 3rd dimension.
Example:
ImageStack(x,y,N) where N = 31 image frames.
2DProjection = max(ImageStack,[],3)
Now, since the 2D projection image is black and white, I was hoping to assign a color gradient so that I can get a sense of the flow of particles through time. Is there a way that I can overlay this image with color, so that I will know where a particle started, and where it ended up?
Thanks!
You could use the second output of max to get which frame the particular maximum came from. max returns an index matrix which indicates the index of each maximal value, which in your case will be the particular frame in which it occurred. If you use this with the imagesc function, you will be able to plot how the particles move with time. For instance:
ImageStack(x,y,N) where N = 31 image frames.
[2DProjection,FrameInfo] = max(ImageStack,[],3);
imagesc(FrameInfo);
set(gca,'ydir','normal'); % Otherwise the y-axis would be flipped
You can sum up bright pixels of each image with one another after coloring each image. This way you will have mixed colors on overlapped areas which you will miss using max function. Although I like the previous answer more than mine.
hStep = 1/N;
currentH = 0;
resultImage = uint8(zeros(x,y,3));
for i = 1 : N
rgbColor = hsv2rgb(currentH,1,0.5);
resultImage(:,:,1) = resultImage(:,:,1) + im(:,:,i) * rgbColor(1);
resultImage(:,:,2) = resultImage(:,:,2) + im(:,:,i) * rgbColor(2);
resultImage(:,:,3) = resultImage(:,:,3) + im(:,:,i) * rgbColor(3);
currentH = currentH + hStep;
end

Using rectangle in Matlab. Using Sum()

I have performed rgb2gray on an image and did a sobel edge detection on the image.
then did
faceEdges = faceNoNoise(:,:) > 50; %binary threshold
so it sets the outline of the image (a picture of a face), to black and white. Values 1 is white pixel, and 0 is black pixel. Someone said I could use this,
mouthsquare = rectangle('position',[recX-mouthBoxBuffer, recY-mouthBoxBuffer, recXDiff*2+mouthBoxBuffer/2, recYDiff*2+mouthBoxBuffer/2],... % see the change in coordinates
'edgecolor','r');
numWhite = sum(sum(mouthsquare));
He said to use two sum()'s because it gets the columns and rows of the contained pixels within the rectangle. numWhite always returns 178 and some decimal numbers.
If you have a 2D matrix M (this being -- for exmple -- an image), the way to count how many elements have the value 1 is:
count_1 = sum(M(:)==1)
or
count_1 = sum(reshape(M,1,[])==1)
If the target values are not exactly 1, but have a Δ-threshold of, let's say, +/- 0.02, then one should ask for:
count_1_pm02 = sum((M(:)>=0.98) & (M(:)<=1.02))
or the equivalent using reshape.

Find area of circle on a grid using euclidean distance?

I would like to have a function where I can input a radius value and have said function spit out the area for that size circle. The catch is I want it to do so for integer based coordinates only.
I was told elsewhere to look at Gauss's circle problem, which looks to be exactly what I'm interested in, but I don't really understand the math behind it (assuming it is actually accurate in calculating what I'm wanting).
As a side note, I currently use a modified circle drawing algorithm which does indeed produce the results I desire, but it just seems so incredibly inefficient (both the algorithm and the way in which I'm using it to get the area).
So, possible answers for this to me would be actual code or pseudocode for such a function if such a thing exists or something like a thorough explanation of Gauss's circle problem and why it is/isn't what I'm looking for.
The results I would hope the function would produce:
Input: Output
0: 1
1: 5
2: 13
3: 29
4: 49
5: 81
6: 113
7: 149
8: 197
9: 253
I too had to solve this problem recently and my initial approach was that of Numeron's - iterate on x axis from the center outwards and count the points within the upper right quarter, then quadruple them.
I then improved the algorithm around 3.4 times.
What I do now is just calculating how many points there are within an inscribed square inside that circle, and what's between that square and the edge of the circle (actually in the opposite order).
This way I actually count one-eighth of the points between the edge of the circle, the x axis and the right edge of the square.
Here's the code:
public static int gaussCircleProblem(int radius) {
int allPoints=0; //holds the sum of points
double y=0; //will hold the precise y coordinate of a point on the circle edge for a given x coordinate.
long inscribedSquare=(long) Math.sqrt(radius*radius/2); //the length of the side of an inscribed square in the upper right quarter of the circle
int x=(int)inscribedSquare; //will hold x coordinate - starts on the edge of the inscribed square
while(x<=radius){
allPoints+=(long) y; //returns floor of y, which is initially 0
x++; //because we need to start behind the inscribed square and move outwards from there
y=Math.sqrt(radius*radius-x*x); // Pythagorean equation - returns how many points there are vertically between the X axis and the edge of the circle for given x
}
allPoints*=8; //because we were counting points in the right half of the upper right corner of that circle, so we had just one-eightth
allPoints+=(4*inscribedSquare*inscribedSquare); //how many points there are in the inscribed square
allPoints+=(4*radius+1); //the loop and the inscribed square calculations did not touch the points on the axis and in the center
return allPoints;
}
Here's a picture to illustrate that:
Round down the length of the side of an inscribed square (pink) in the upper right quarter of the circle.
Go to next x coordinate behind the inscribed square and start counting orange points until you reach the edge.
Multiply the orange points by eight. This will give you the yellow
ones.
Square the pink points. This will give you the dark-blue ones. Then
multiply by four, this will get you the green ones.
Add the points on the axis and the one in the center. This gives you
the light-blue ones and the red one.
This is an old question but I was recently working on the same thing. What you are trying to do is as you said, Gauss's circle problem, which is sort of described here
While I too have difficulty understaning the serious maths behind it all, what it more or less pans out to when not using wierd alien symbols is this:
1 + 4 * sum(i=0, r^2/4, r^2/(4*i+1) - r^2/(4*i+3))
which in java at least is:
int sum = 0;
for(int i = 0; i <= (radius*radius)/4; i++)
sum += (radius*radius)/(4*i+1) - (radius*radius)/(4*i+3);
sum = sum * 4 + 1;
I have no idea why or how this works and to be honest Im a bit bummed I have to use a loop to get this out rather than a single line, as it means the performance is O(r^2/4) rather than O(1).
Since the math wizards can't seem to do better than a loop, I decided to see whether I could get it down to O(r + 1) performance, which I did. So don't use the above, use the below. O(r^2/4) is terrible and will be slower even despite mine using square roots.
int sum = 0;
for(int x = 0; x <= radius; x++)
sum += Math.sqrt(radius * radius - x * x);
sum = sum * 4 + 1;
What this code does is loop from centre out to the edge along an orthogonal line, and at each point adding the distance from line to edge in a perpendicualr direction. At the end it will have the number of points in a quater, so it quadruples the result and adds one because there is also central point. I feel like the wolfram equation does something similar, since it also multiplies by 4 and adds one, but IDK why it loops r^2/4.
Honestly these aren't great solution, but it seems to be the best there is. If you are calling a function which does this regularly then as new radii come up save the results in a look-up table rather than doing a full calc each time.
Its not a part of your question, but it may be relevant to someone maybe so I'll add it in anyway. I was personally working on finding all the points within a circle with cells defined by:
(centreX - cellX)^2 + (centreY - cellY)^2 <= radius^2 + radius
Which puts the whole thing out of whack because the extra +radius makes this not exactly the pythagorean theorem. That extra bit makes the circles look a whole lot more visually appealing on a grid though, as they don't have those little pimples on the orthogonal edges. It turns out that, yes my shape is still a circle, but its using sqrt(r^2+r) as radius instead of r, which apparently works but dont ask me how. Anyway that means that for me, my code is slightly different and looks more like this:
int sum = 0;
int compactR = ((radius * radius) + radius) //Small performance boost I suppose
for(int j = 0; j <= compactR / 4; j++)
sum += compactR / (4 * j + 1) - compactR / (4 * j + 3);
sum = sum * 4 + 1;

Convert from coordinates to pixels

I am implementing a rightclick context menu on my google v3 map and I need to get the pixel x and y to correctly position the menu. I get the lat and the lng, anyone have a nice solution to get the pixel x and y?
Best Regards
Henkemota
index=x+(y*height)
x = index % width
y = index / height
Correction to the above answer:
index=x+(y*width)
//(not y*height ... because you're taking one full horizontal line of pixels (e.g. 1280px) and multiplying that by the number of lines (y) down the screen at which x is, then adding x to account for x pixels over in the next full line.)
x = index % width
y = index / height