JES - Alter the amount of red of an image - python

I need to decrease the amount of red in a pixel by 50% on the top half of the image and then increase bottom half by 50%
def changeRed():
setMediaPath("/Users/addison/Downloads/Cmpt101_Pics/Learjet31A.jpg")
filename1 = "/Users/addison/Downloads/Cmpt101_Pics/Learjet31A.jpg"
source = makePicture(filename1)
halfWidth = getWidth(source)/2
for y in range(0,getHeight(source)):
for x in range(0, halfWidth):
pixel = getPixel(source, x, y)
value = getRed(pixel)
setRed(pixel, value-127.5)
show(source)
This is what I have right now, I'm not sure how to change it to make it halved on the X axis instead of the Y axis which it currently does right now..I have attempted to look everywhere for the solution but can't seem to find anything...Help Please

All you need to do is swap the x and y in the for loops. For example
for x in range(0, getWidth(source)):
for y in range(0, halfHeight):
# Do stuff

Related

How do I create a binary mask on a square grid from a 2D cloud of points in Python?

I have a the X and Y coordinates of a 2D cloud of points that I want to map onto a 2D uniform grid with a resolution of imageResolution of initially all zeros. I want all pixels in the grid which overlay the 2D cloud of points to contain ones, to produce a binary image.
Please note, there are a very large number of points both in my 2D cloud of points and in the uniform grid, and so loops are not an effective solution here.
I have looked at convex hulls but my points are not necessarily in a convex set.
I have tried this following code, but its not giving me the correct binary map, since its only assigning 1s to the nearest grid points closest to the points in the point cloud (see image below):
X = points[:,0] #1D array of X coordinates
Y = points[:,1] #1D array of Y coordinates
imageResolution = 256
xVec = np.linspace(0,800,imageResolution)
yVec = xVec
def find_index(x,y):
xi=np.searchsorted(xVec,x)
yi=np.searchsorted(yVec,y)
return xi,yi
xIndex, yIndex = find_index(X,Y)
binaryMap = np.zeros((imageResolution,imageResolution))
binaryMap[xIndex,yIndex] = 1
fig = plt.figure(1)
plt.imshow(binaryMap, cmap='jet')
plt.colorbar()
Please see this image which shows my 2D cloud of points, the desired binary map I want, and the current binary map I am getting from the code above. Please note the red pixels are difficult to see in the last image.
How do I create a binary mask on a square grid from a 2D cloud of points in Python?
Thank you
DISCLAIMER :: Untested suggestion
If I've understood correctly, rather than mark an individual pixel with 1, you should be marking a neighborhood of pixels.
You could try inserting the following lines just before binaryMap[xIndex,yIndex] = 1:
DELTA_UPPER=2 # Param. Needs fine-tuning
delta = np.arange(DELTA_UPPER).reshape(-1,1)
xIndex = xIndex + delta
xIndex [xIndex >= imageResolution] = imageResolution-1
yIndex = yIndex + delta
yIndex [yIndex >= imageResolution] = imageResolution-1
x_many, y_many = np.broadcast_arrays (xIndex[:,None], yIndex)
xIndex = x_many.reshape(-1)
yIndex = y_many.reshape(-1)
Note:
DELTA_UPPER is a parameter that you will have to fine-tune by playing around with. (Maybe start with DELTA_UPPER=3)
UNTESTED CODE
Based on further clarifications, posting this second answer, to better index the binaryMap, given that points contains floats.
imageResoluton = 256
MAX_X = # Fill in here the max x value ever possible in `points`
MIN_X = # Fill in here the min x value ever possible in `points`
MAX_Y = # Fill in here the max y value ever possible in `points`
MIN_Y = # Fill in here the min y value ever possible in `points`
SCALE_FAC = imageResolution / max(MAX_X-MIN_X, MAX_Y-MIN_Y)
X = np.around(SCALE_FAC * points[:,0]).astype(np.int64)
Y = np.around(SCALE_FAC * points[:,1]).astype(np.int64)
X [X >= imageResolution] = imageResolution-1
Y [Y >= imageResolution] = imageResolution-1
binaryMap[X, Y] = 1
(There's no need for find_index())

Creating a Simulation of Equipotencial Surfaces in Python with numpy/matplotlib

I have a 3D array where I added the potential values for each coordinate here:
z = y = x = size # size of each side of the cube
potential = np.zeros((z, y, x))
exemple: I set a potential to a point -> potential[3,3,3] = 10 now this coord has a value of 10. And the surrounding points will have a potential based on the mean of the surrounding points.
such as:
for z in range(1,size):
for y in range(1,size):
for x in range(1,size):
if [z,y,x] in polop:
potential[z,y,x] = Positive # If positive polo, keeps potential
elif [z,y,x] in polon:
potential[z,y,x] = Negative # If negative polo, keeps potential
elif z!=size-1 and y!=size-1 and x!=size-1: # Sets the potential to the mean potential of neighbors
potential[z][y][x] = (potential[z][y][x+1] + potential[z][y][x-1] + potential[z][y+1][x] +
potential[z][y-1][x] + potential[z+1][y][x] + potential[z-1][y][x]) / 6
Then I plotted this array and it looks like this:
Now what I want is to have surfaces instead of scattering points. A surface consisting of the points that have more less the same potential (let's say from 2 in 2, as 10->8, 8->6, 6->4, 4->2, 2->0, 0->-2, etc.)
Is it possible?
Plus, this was supposed to be an ellipsoid instead of a cube, the poles were supposed to be spheres instead of cubes and this needs to be updating like each second.
Please help!

Python/Pygame: How to make buttons scale on screen with amount of buttons and screen size?

Basically i am writing a program that looks sort of like a control panel in python/pygame. Its purpose is to read a number of files with a certain file extension, count them, and then draw a number of buttons on the control panel according to the corresponding amount of files counted.
I have achieved this, but my one problem is that i need to be able to make the buttons form in organized rows within the restrictions of the given screen. However, I am not quite sure how to approach this so i decided to try stackoverflow to see if anybody has been able to overcome this endeavor before.
The code is as follows:
def Button_Build(gamesnum): # 'gamesnum' is the amount of detected files
Screensize = 200 #size of given screen space
button_size = Screensize/len(gamesnum) * 2 #Size of the button according to amount of files found/size of screen
x = 9 #button's original x coordinate
y = 20 #button's original y coordinate
butrow = 0 #Counter for how many buttons that can fit inside of the given screen space
butmax = 0 #Maximum amount of buttons that can fit inside of given screen space
for i in gamesnum: #Going through the number of files counted
print(x) #Print the drawn buttons' x coordinate
#If next button doesn't go out of given screen space
if x < Screensize - (Screensize/int(len(gamesnum))):
lebutton=GUI_Helper(white, red9, x, y)
lebutton.Standard_button_make(button_size, button_size-2)
x += (button_size + 2)
butrow += 1
#When maximum amount of buttons that can fit across the screen is reached
if butrow == butmax:
butrow = 0 #Reset the counter
x = 9 #Reset button's x coordinate
y += (button_size + 2) #Move next buttons down a row
pygame.display.update()
So as you can see, i am still quite the amateur at programming and as such i truly apologize for how hard it may be to understand my code written above. If I need to clarify anything or answer any questions, let me know and i will do my best to answer them!
Thanks in advance!
~Dachua
I have tried to reuse as much of your code as I could but there are a couple of big item you might want to address - you are using button_size calculated for x but not y - this will produce square buttons, and you never use any kind of text or description of the files for the buttons. That being said this code should produce the results you want:
def Button_Build(gamesnum): # 'gamesnum' is the amount of detected files
Screensize = 200 #size of given screen space
button_size = Screensize/len(gamesnum) * 2 #Size of the button according to amount of files found/size of screen
StartX = 9
StartY = 20
x = StartX #button's original x coordinate
y = StartY #button's original y coordinate
butrow = 0 #Counter for how many buttons that can fit inside of the given screen space
butmax = int(ScreenSize / (button_size + 2)) #Maximum amount of buttons that can fit inside of given screen space
for i in gamesnum: #Going through the number of files counted
print(x) #Print the drawn buttons' x coordinate
#If next button doesn't go out of given screen space
if butrow < butmax:
lebutton=GUI_Helper(white, red9, x, y)
lebutton.Standard_button_make(button_size, button_size-2)
x += (button_size + 2)
butrow += 1
else:
#When maximum amount of buttons that can fit across the screen is reached
butrow = 0 #Reset the counter
x = StartX #Reset button's x coordinate
y += (button_size + 2) #Move next buttons down a row
pygame.display.update()

moving a rectangle to a specific point

I am trying to move a rectangle to a specific point with a specific speed.
however it only works properly if x,y (the point i am trying to move it to) are the same. otherwise, if x was bigger than y it would move at a 45 degree angle until self.location[1]==y(it reached where it needed to be for y), then it would move in a straight for x and vise versa.
i know that i would have to change speed_y so that it was slower. how do i work out what speed i need y to be at in order to get the rectangle to move to location in a straight line no matter what location is?
full function:
def move(self,x,y,speed):
if speed==0:
self.location=[x,y]
else:
speed_x = speed
speed_y = speed
if x > 0 and not self.location[0]==x: # x is positive and not already where it needs to be
if not x == y:
speed_x = something # need to slow down the speed so that it gets to y as the same time as it gets to x
self.speed_x=speed_x
else: self.speed_x=0
if y > 0 and not self.location[1]==y: # same for y
if not x == y:
speed_y = something # need to slow down the speed so that it gets to y as the same time as it gets to x
self.speed_y=speed_y
else: self.speed_y=0
You should set your speeds to a ratio of required distance for each axis.
e.g. if distance to x is half distance to y then speed_x should be half speed_y.
Further example as requested:
distance_x = x-self.location[0]
distance_y = y-self.location[1]
if abs(distance_x) < abs(distance_y):
ratio = distance_x/abs(distance_y)
speed_x = ratio * speed
edit: Reworked the directions of example.
I don't quite get what you are asking for, but see if this helps you:
speed_x = speed*(cos(atan2((y-self.location[1]), (x-self.location[0]))))
speed_y = speed*(sin(atan2((y-self.location[1]), (x-self.location[0]))))
That would "slow" the speed you are given by splitting it in the values needed to get to where you want your box to be at the same time.
Pardon any errors in my english/python, im not native on either one :)
You need mathematical calculations to get new position in every move.

Copying a triangular area from one picture to another in Python

I am trying to write a python function that will copy a triangular area from anywhere on a picture to a new blank picture. I can copy a rectangular area from a picture to a new empty picture, but I just don't know how to copy a triangle. That's what I have, but it only copies a rectangular area. Sorry if it looks messy or over-complicated, but I'm just starting how to write in python.
def copyTriangle():
file=pickAFile()
oldPic=makePicture(file)
newPic=makeEmptyPicture(getWidth(oldPic),getHeight(oldPic))
xstart=getWidth(oldPic)/2
ystart=getHeight(oldPic)/2
for y in range(ystart,getHeight(oldPic)):
for x in range(xstart,getWidth(oldPic)):
oldPixel=getPixel(oldPic,x,y)
colour=getColor(oldPixel)
newPixel=getPixel(newPic,x,y)
setColor(newPixel,colour)
Function to copy a triangular area from one pic to another.
def selectTriangle(pic):
w= getWidth (pic)
h = getHeight(pic)
newPic = makeEmptyPicture(w,h)
x0=107#test point 0
y0=44
x1=52#test point 1
y1=177
x2=273 #test point 2
y2=216
#(y-y0)/(y1-y0)=(x-x0)/(x1-x0)
for y in range (0,h):
for x in range (0, w):
#finding pixels within the plotted lines between eat set of points
if (x>((y-y0)*(x1-x0)/(y1-y0)+x0) and x<((y-y0)*(x2-x0)/(y2-y0)+x0) and x>((y-y2)*(x1-x2)/(y1-y2)+x2)):
pxl = getPixel(pic, x, y)
newPxl= getPixel(newPic,x,y)
color = getColor(pxl)
setColor (newPxl, color)
return (newPic)
If you're willing to do it pixel by pixel as in your example, then just copy the pixels of the triangle. Mostly this depends on how you want to define the triangle.
The simplest triangle is to make your x range (inner loop) dependent on your y-value (outer loop), like:
for y in range(ystart, ystart+getHeight(oldPic)):
for x in range(xstart, xstart + int( getWidth(oldPic)*((y-ystart)/float(getHeight)):
More generally, you could still keep your same x and y loops, and then put the copying commands in an if block, where you check whether the point is in your triangle.
Beyond this, there are much more efficient ways of doing this, using masks, etc.
Note, also here I changed the y-range to range(ystart, ystart+getHeight(oldPic)), which I think is probably what you want for a height that doesn't depend on the starting position.

Categories

Resources