Kivy GUI window
In the above GUI window I have a fish masked image and a fish tank which is the main background image. I want to extract the absolute lower left coordinate of the scatter to perform further cropping operation on the image and with the scatter mask. Scatter.bbox or scatter.pos is not returning absolute X,Y coordinates w.r.t image. When angle is less than 12deg it is working fine but as angle is increased new bbox rectangle translates more towards the bottom part of the window.
code for this:
`x = scatter.bbox[0][0]
y = scatter.bbox[0][1]
#I have also tried - self.to_local(*self.scatter.pos)`
For getting absolute coordinates use to_parent instead of bbox:
scatter_name.to_parent(0,0)
Related
My project is about image detection. I am using 1 camera and have 2 shapes (rectangle and triangle) placed on a flat surface. I have successfully been able to:
Detect the contours
Detect the area of the contours
Make a relation between both areas and the distances, to be able to calculate both distances from the camera
Calculate the lengths, corner coordinates and the angle of each corner in both shapes
Now I need to calculate the angle of rotation of the whole surface when rotated around the x-axis (up & down), y-axis (left & right) and both axes (oblique). This can be seen in the gif I provided. The default angle (0 degrees) is when the surface is parallel to the camera, and any rotation would mean that an angle around 1 or both axes is present.
P.S When the surface is rotating around both axes (oblique), both angles have to be detected separately. For example, I would get 14° x-axis & 27° y-axis.
Any help would be appreciated.
I want to visualize results of keypoint tracking algorithm in python. I have a sequence of (Image, Keypoint) pairs (video basically). Tracking algorithm is strong enough to give me subpixel accuracy. But i have no idea, how to visualize it properly.
I tried to round my coordinates and draw a circle by cv2.circle(image, (int(round(x)), int(round(y)))), but it leads to visual jittering of my keypoints due to small image resolution.
I checked OpenCV, Pillow, skimage, Pygame (pygame.draw.circle). All of them cannot properly draw circle with float coordinates.
DIPlib has the function DrawBandlimitedBall(), which draws a disk or a circle with smooth transitions and with floating-point origin coordinates (disclosure: I'm one of the authors). You might need to draw the circle in an empty image, then blend it in to get the effect you are looking for. Code would look something like this:
import diplib as dip
img = dip.ImageRead('/Users/cris/dip/images/flamingo.tif')
p = [366.4, 219.1]
# Create an empty image and draw a circle in it
circle = dip.Image(img.Sizes(), 1, 'SFLOAT')
circle.Fill(0)
dip.DrawBandlimitedBall(circle, diameter=22.3, origin=p, value=1, mode='empty')
circle /= dip.Maximum(circle)
# Blend: img * (1-circle) + circle * color
img *= 1 - circle
img += circle * dip.Create0D([0,255,0]) # we make the circle green here
img.Show()
dip.ImageWrite(img, 'so.jpg')
(Note that the circle actually looks better without the JPEG compression artifacts.)
You could draw the circle directly in the image, but this function adds the circle values to the image, it doesn't attempt to blend, and so you'd get a much worse look for this particular application.
I'm currently cropping images this way:
self.crop = self.img[self.y_center - self.radius:self.y_center + self.radius,
self.x_center - self.radius:self.x_center + self.radius:, ]
Where y_center and x_center are defined by clicks, and radius is the size of the crop. But I repeatedly run into a problem where the click is on an extreme side of an image. In that case, how do I extend the side on the other side of the image?
Basically I do not want to compromise the size.
The simple & stupid (r) way:
check if the rectangle around the point goes beyond the image
move it the corresponding amount of pixels if it does
repeat for all the 4 sides
Not so s&s is how to handle the case where the rectangle is larger than the entire image, but we'll see...
# X,Y - size of the image - 1 (maximum possible values for x,y)
# x,y - click coordinates relative to the image
t=x+radius; if t>X: x-=t-X
t=y+radius; if t>Y: y-=t-Y
t=x-radius; if t<0: x-=t #t<0 so it's increased actually
t=y-radius; if t<0: y-=t
del t
crop = img[x-radius:min(x+radius,X), y-radius:min(y+radius,Y)]
With min, we handle the case when the rectangle is larger than the image.
We check from the "high" side because we chose the order of adjustments so that the last ones have docked the rectangle to the "low" side.
I am trying to draw a tilted ellipse in image draw. However, I am not sure how to define it, since while the scheme below would move the points, I think this would just squish the ellipse, not rotate it (also I think there is something slightly wrong with the transformation in any case). I am feeding the output of this function into the ellipse command and adding it to an existing picture, so any methods that would rotate the entire image are no good. OD is just a square offset to the coordinate center I am using.
def ellipsebound(major, minor, tilt=0, offset=0, angle=0):
#creates a bound for an ellispe, defined with tilt meaning to rotate the orthogonal axis and angle corresponds to rotating the ellipse position
angle = radians(angle)
tilt = radians(tilt)
box=(
1 + int(ceil((OD+offset*cos(angle)+(major*cos(tilt)+minor*sin(tilt)))/conv)),
1 + int(ceil((OD+offset*sin(angle)+(major*sin(tilt)-minor*cos(tilt)))/conv)),
int(ceil((2*OD-(OD-offset*cos(angle)-(major*cos(tilt)+minor*sin(tilt)))/conv))),
int(ceil((2*OD-(OD-offset*sin(angle)-(major*sin(tilt)-minor*cos(tilt)))/conv)))
) #create bounding box
return box
Does anyone know how to accomplish this?
It looks like the 'box' that is being used to draw the ellipse has no rotation associated with it. It is simply defined by the (left, top, right, bottom) extents.
One possible workaround (depending on what you need to do) is to draw the ellipse (sized correctly, but without the rotation) onto an intermediary image, use the image.rotate() method, and then paste it into your target image.
I hope that helps.
What would be the best way to use negative coordinates in pygame?
At the moment I have a surface that is 1.5 times the original surface then everything that needs to be drawn is shifted up by a certain amount (to ensure the negative coordinates become positive) and drawn.
Is there an easier/alternate way of doing this?
A simple solution is to write a linear mapping function from world coordinates to pygame screen coordinates
def coord(x,y):
"Convert world coordinates to pixel coordinates."
return 320+170*x, 400-170*y
and use it when drawing all world objects. Have a look here for a complete example.
There is no way to move the origin of a surface from 0,0.
Implement your own drawing class which transforms all the coordinates passed in into the space of the surface.
If it's similar to an RPG map situation, where you have world coordinates and screen coordinates:
use a function that translates world to local, and vice versa.
But I wasn't sure I'd you were looking for Rect's properties?
rect.bottomright = (width, height) # bottom right at window corner
If you want to use center coordinates to blit, vs top left being (0,0)
ship.rect.center = (20, 30) # don't need to translate by adding w/2 to topleft
See also: Rect.move_ip()