Pygame, rotating images by axis - python

Im trying to rotate a loaded image but I need it rotated by a specific axis.
I was doing this:
arm = pygame.image.load('w1.png').convert()
arms = [pygame.transform.rotate(arm, deg) for deg in range(0, 360, 4)]
I was then iterating through the indicies of arms with:
count+=1
arms[count]
The rotation does work but it is not rotating on the axis properly. I have written algorithms that rotate lines made with pygame.draw.line but I do not know how to achieve this with an image.
Any and all insight appreciated,
thanks

After rotating your image, and before blitting, get the new rect for the image, and change the positional attributes of the rect back to the original position.
IE: save rect center, rotate image, get new rect, set newrect center, blit.
Using the center attribute with only rotate it around the center of the image, but maybe using one of the corners will put you on the right path.
def RESET_ROTATED_RECT(old_rect,rotated_image):
old_pos=old_rect.center
newrect=rotated_image.get_rect()
newrect.center=old_pos
return newrect
I use the center often, but haven't used the other positions. It may be worth tinkering with.

Related

Detect circular segment in the image

I am trying to determine the circle parameters, using its slice, visible in the image. I want to know the radius, coordinates of center and draw the full circle (on the bigger picture of course). I've tried to use imfindcircles with Hough Transformation. Unfortunately, it looks like the slice of the circle is not big enough, and the algorithm does not recognize it as the full circle.
clear all;
close all;
figure();
image = imread('circle3.jpg');
imshow(image);
Rmin = 10;
Rmax = 10000;
[centersBright, radiiBright] = imfindcircles(image,[Rmin
Rmax],'ObjectPolarity','bright','Method','TwoStage','Sensitivity',0.98,'EdgeThreshold',0.9);
viscircles(centersBright, radiiBright,'Color','b');
I have changed the sensivity, threshold, Rmin, Rmax, even the method, but still, nothing happens. How can I detect this circle, if not in Matlab, then maybe in Python?

pixel value change after image rotate

Is it possible the value pixel of image is change after image rotate? I rotate an image, ex, I rotate image 13 degree, so I pick a random pixel before the image rotate and say it X, then I brute force in image has been rotate, and I not found pixel value as same as X. so is it possible the value pixel can change after image rotate? I rotate with opencv library in python.
Any help would be appreciated.
Yes, it is possible for the initial pixel value not to be found in the transformed image.
To understand why this would happen, remember that pixels are not infinitely small dots, but they are rectangles with horizontal and vertical sides, with small but non-zero width and height.
After a 13 degrees rotation, these rectangles (which have constant color inside) will not have their sides horizontal and vertical anymore.
Therefore an approximation needs to be made in order to represent the rotated image using pixels of constant color, with sides horizontal and vertical.
If you just rotate the same image plane the image pixels will remain same. Simple maths

Pygame circle collision?

I am using pygame to make a simple game. I am having issues with circle collisions. I am getting the following error:
"AttributeError: 'pygame.Rect' object has no attribute 'rect'"
Here is the particular code I am having issues with below:
if pygame.sprite.collide_circle(hero_circle, enemy_circle):
gameover()
Use pygame.mask to create a collision mesh for your objects and use the mesh to do collision detections.
In more detail:
Create an image file for both of your circles and set the bg color to something you will not use anywhere else.
Set that color to "transparent" in your image editor.
Import the images.
Create a mesh for them with pygame.mask and set it to make transparent pixels non-collidable.
Use the generated mask as your collision detection mesh.
PROFIT
(Technically this is just doing collision detection of a circle shaped area on a rectangle, but who cares!)
pygame.draw.rect()
draw a rectangle shape
rect(Surface, color, Rect, width=0) -> Rect
Draws a rectangular shape on the Surface. The given Rect is the area of the rectangle. The width argument is the thickness to draw the outer edge. If width is zero then the rectangle will be filled.
Keep in mind the Surface.fill() method works just as well for drawing filled rectangles. In fact the Surface.fill() can be hardware accelerated on some platforms with both software and hardware display modes.
The best way I've found to check circle collision detection is to calculate the distance between the center points of two circles. If the distance is less than the sum of the two circle's radii, then you've collided.
Just like how gmk said it but if your are using circles instead of rectangles, you should use this pygame function :
pygame.draw.circle(surface, color, center_point, radius, width)
This draws a circle on your surface (which would go in the surface area). Clearly the color requires a list of numbers (RGB anyone?). Your center_point decides the location of your circle since it will be the location of the center of your circle. The radius will need a number to set the radius of the circle (using the number like 25 will set your radius at 25 pixels/diameter at 50 pixels). the width section is optional as it sets the thickness of the perimeter of your circle (having 0 will have none at all). If you are not using circles, you should change your title... But anyways, I hope this helps you!

Programmatically remove Apple Screen Capture Shadow borders

The built-in MacOS screen capture program (command-shift-4) has a nice feature where you can hit the spacebar and capture just a window, like this:
I would like to programmatically look at a directory of images (they are PNGs), determinate if they have the shadow, and automatically crop it. I need this to run on a Mac. I'd like to write this in Python. I am told that Pillow is the correct way to manage images in Python now, but I'm not sure how to read individual pixel and to crop images.
Here are some recommendations regardless of the library you will be using.
There are invariants on the window: 4 corners, title bar with mostly uniform color and 3 disk-shaped buttons.
If you can detect the buttons and the title bar, you can easily find the top corners. The bottom corners are symmetrical to the top corners.
A possible solution
Apply Hough transform to find circles
Find 3 consecutive circles along the horizontal axis (the buttons)
Apply Hough transform to find vertical and horizontal lines
Find a quad containing the 3 circles (title bar)
The 2 top corners of the window are located around the top corners of the title bar.
Form a patch by taking a neighborhood around a corner
Apply an edge detection algorithm in the patch
Reflect the pixels of the patch vertically
Apply patch matching vertically. For example with DP
Repeat the matching for the 2 top corners to find the bottom ones
With the 4 corner you know the bounding box of the window and you can solve the cropping problem
Here is code that uses Python Image Library and Python 2.7 to do the trick:
#!/usr/bin/env
# Removes the shadow from MacOS-Generated screen shots.
import Image,os
if __name__=="__main__":
image = Image.open(os.sys.argv[1])
image = image.convert('RGBA')
(width,height) = image.size
def find_first_non_alpha_x():
for i in range(width):
if image.getpixel((i,height/2))[3]==255:
return i
raise RuntimeError("No non-alpha pixels on midline")
def find_last_non_alpha_x():
for i in range(width-1,0,-1):
if image.getpixel((i,height/2))[3]==255:
return i
raise RuntimeError("No non-alpha pixels on midline")
def find_first_non_alpha_y():
for i in range(height):
if image.getpixel((width/2,i))[3]==255:
return i
raise RuntimeError("No non-alpha pixels on midline")
def find_last_non_alpha_y():
for i in range(height-1,0,-1):
if image.getpixel((width/2,i))[3]==255:
return i
raise RuntimeError("No non-alpha pixels on midline")
x1 = find_first_non_alpha_x()
y1 = find_first_non_alpha_y()
x2 = find_last_non_alpha_x()
y2 = find_last_non_alpha_y()
y = image.crop((x1-1,y1-1,x2+1,y2+1))
y.save(os.sys.argv[1]+"-cropped.png")

Weird shifting when using pygame.transform.rotate()

def rotate(self):
#Save the original rect center
self.saved_center=self.rect.center
#Rotates a saved image every time to maintain quality
self.image=pygame.transform.rotate(self.saved_image, self.angle)
#Make new rect center the old one
self.rect.center=self.saved_center
self.angle+=10
When I rotate the image, there is a weird shifting of it despite the fact that I'm saving the old rect center and making the rotated rect center the old one. I want it to rotate right at the center of the square.
Here's what it looks like:
http://i.imgur.com/g6Os9.gif
You are just calculating the new rect wrong. Try this:
def rotate(self):
self.image=pygame.transform.rotate(self.saved_image, self.angle)
self.rect = self.image.get_rect(center=self.rect.center)
self.angle+=10
It tells the new rect to center itself around the original center (the center never changes here. Just keeps getting passed along).
The issue was that the self.rect was never being properly updated. You were only changing the center value. The entire rect changes as the image rotates because it grows and shrinks in size. So what you needed to do was completely set the new rect each time.
self.image.get_rect(center=self.rect.center)
This calculates a brand new rect, while basing it around the given center. The center is set on the rect before it calculate the positions. Thus, you get a rect that is properly centered around your point.
I had this issue. My method has a bit of a different purpose, but I solved it quite nicely.
import pygame, math
def draw_sprite(self, sprite, x, y, rot):
#'sprite' is the loaded image file.
#'x' and 'y' are coordinates.
#'rot' is rotation in radians.
#Creates a new 'rotated_sprite' that is a rotated variant of 'sprite'
#Also performs a radian-to-degrees conversion on 'rot'.
rotated_sprite = pygame.transform.rotate(sprite, math.degrees(rot))
#Creates a new 'rect' based on 'rotated_sprite'
rect = rotated_sprite.get_rect()
#Blits the rotated_sprite onto the screen with an offset from 'rect'
self.screen.blit(rotated_sprite, (x-(rect.width/2), y-(rect.height/2)))

Categories

Resources