Can't find info on how to just draw a border around a circle. Simply looking to draw a circle with a black border just like the BorderedRectangle function.
import pyglet
from pyglet import shapes
def display_get_width():
display = pyglet.canvas.get_display()
screen = display.get_default_screen()
return screen.width
def display_get_height():
display = pyglet.canvas.get_display()
screen = display.get_default_screen()
return screen.height
screen_width = display_get_width()
screen_height = display_get_height()
print(screen_width, screen_height)
window = pyglet.window.Window(screen_width//2,screen_height//2)
batch = pyglet.graphics.Batch()
rectangle = shapes.BorderedRectangle(250, 300, 600, 300, border=1, color=(255, 255, 255), border_color=(100, 100, 100), batch=batch)
rectangle2 = shapes.BorderedRectangle(300, 350, 300, 150, border=1, color=(255, 255, 255), border_color=(100, 100, 100), batch=batch)
circle = shapes.Circle(550, 450, 100, color=(50, 225, 30), batch=batch)
#window.event
def on_draw():
window.clear()
batch.draw()
pyglet.app.run()
It's been a year and half, but I had the same question a moment ago. I solved it by drawing shapes.ARC and setting width with a GL function:
pyglet.gl.glLineWidth(5)
arc = shapes.Arc(200, 200, 150, color=(255, 0, 0), batch = batch)
Omitting "angle" parameter while creating an Arc instance assumes angle is 2π - a full circle.
You can make a circle inside another circle:
circle = shapes.Circle(550, 450, 100, color=(50, 225, 30), batch=batch)
insideCircle = shapes.Circle(550, 450, 80, color=(30, 205, 10), batch=batch)
Related
I tried to draw an NBA court using matplotlib. I found the code from here but it's a 2D drawing. I modified a few lines and using art3d.pathpatch_2d_to_3d to transform all patches to a 3d plot. Everything works well except for Arc which shows a full circle.
from matplotlib.patches import Circle, Rectangle, Arc
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import art3d
def draw_court(ax=None, color='black', lw=2, outer_lines=False, ax_3d=False):
# If an axes object isn't provided to plot onto, just get current one
if ax is None:
ax = plt.gca()
# Create the various parts of an NBA basketball court
# Create the basketball hoop
# Diameter of a hoop is 18" so it has a radius of 9", which is a value
# 7.5 in our coordinate system
hoop = Circle((0, 0), radius=7.5, linewidth=lw, color=color, fill=False)
# Create backboard
backboard = Rectangle((-30, -7.5), 60, -1, linewidth=lw, color=color)
# The paint
# Create the outer box 0f the paint, width=16ft, height=19ft
outer_box = Rectangle((-80, -47.5), 160, 190, linewidth=lw, color=color,
fill=False)
# Create the inner box of the paint, widt=12ft, height=19ft
inner_box = Rectangle((-60, -47.5), 120, 190, linewidth=lw, color=color,
fill=False)
# Create free throw top arc
top_free_throw = Arc((0, 142.5), 120, 120, theta1=0, theta2=180,
linewidth=lw, color=color, fill=False)
# Create free throw bottom arc
bottom_free_throw = Arc((0, 142.5), 120, 120, theta1=180, theta2=0,
linewidth=lw, color=color, linestyle='dashed')
# Restricted Zone, it is an arc with 4ft radius from center of the hoop
restricted = Arc((0, 0), 80, 80, theta1=0, theta2=180, linewidth=lw,
color=color)
# Three point line
# Create the side 3pt lines, they are 14ft long before they begin to arc
corner_three_a = Rectangle((-220, -47.5), 0, 140, linewidth=lw,
color=color)
corner_three_b = Rectangle((220, -47.5), 0, 140, linewidth=lw, color=color)
# 3pt arc - center of arc will be the hoop, arc is 23'9" away from hoop
# I just played around with the theta values until they lined up with the
# threes
three_arc = Arc((0, 0), 475, 475, theta1=22, theta2=158, linewidth=lw,
color=color)
# Center Court
center_outer_arc = Arc((0, 422.5), 120, 120, theta1=180, theta2=0,
linewidth=lw, color=color)
center_inner_arc = Arc((0, 422.5), 40, 40, theta1=180, theta2=0,
linewidth=lw, color=color)
# List of the court elements to be plotted onto the axes
court_elements = [hoop, backboard, outer_box, inner_box, top_free_throw,
bottom_free_throw, restricted, corner_three_a,
corner_three_b, three_arc, center_outer_arc,
center_inner_arc]
if outer_lines:
# Draw the half court line, baseline and side out bound lines
outer_lines = Rectangle((-250, -47.5), 500, 470, linewidth=lw,
color=color, fill=False)
court_elements.append(outer_lines)
# Add the court elements onto the axes
for element in court_elements:
ax.add_patch(element)
if ax_3d:
art3d.patch_2d_to_3d(element, z=0, zdir="z")
return ax
if __name__ == "__main__":
fig = plt.figure()
ax = fig.add_subplot(121, projection='3d')
ax.set(xlim3d=(-300, 500), xlabel='X')
ax.set(ylim3d=(-300, 500), ylabel='Y')
ax.set(zlim3d=(0, 300), zlabel='Z')
draw_court(lw=1, outer_lines=True, ax_3d=True)
ax2 = fig.add_subplot(122)
ax2.set_xlim(-300, 500)
ax2.set_ylim(-100, 500)
draw_court(outer_lines=True)
plt.show()
Result:
Version:
matplotlib 3.5.3
I found the same problem here which is a known bug. However, I can not find the solution.
Edited:
I found the solution from the discussion here.
I just edited patches.py and added
self._path = Path.arc(self.theta1, self.theta2)
to the Arc class init function. (in my case, line 1913).
Edited result:
However, following the discuss, they said the arc length is incorrect. In my case, the problem is that, there is additional line from one end to another end of the Arc.
Is there another solution for this problem?
Thank you.
I try to use QGraphicsPathItem draw a rounded rectange, and then add a hole in the rectange.I think it can do in the paint method, but the performance is not well. So is't there have a good way to draw the shape?
Code Snippet
class Item(QGraphicsPathItem):
def __init__(self):
super().__init__()
path = QPainterPath()
path.addRect(-30, -39, 60, 78)
path.addEllipse(QPoint(-30, 0), 39, 39)
path.addEllipse(QPoint(30, 0), 39, 39)
#add a hole
path.addEllipse(QPoint(0, 0), 28.5, 28.5)
# path.setFillRule(Qt.WindingFill)
self.setBrush(Qt.blue)
self.setPath(path)
Wanted shape
My shape
I am trying to measure the size and count of bubbles available in image taken from real world material particles.
I have tried the approach present Here (second one with opencv). But some how it doesnt work probably because of the bubbles, because image is kind of an average quality.
Can some one please direct me to correct direction or provide recommendation?
The reference image, i am trying process is
Result:
It doesn't detects the circles, in fact at finding contours step, it gets a zero therefore the test is not passed.
Made some changes. Able to detect some bubbles but still not good. Detected bubble image is below
Thanks
Code:
import cv2
image = cv2.imread('....')
# Gray, blur, adaptive threshold
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (11,5), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Morphological transformations
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
# Find contours
cnts = cv2.findContours(opening, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
# Find perimeter of contour
perimeter = cv2.arcLength(c, True)
# Perform contour approximation
approx = cv2.approxPolyDP(c, 0.04 * perimeter, True)
if len(approx) > 6:
# Obtain bounding rectangle to get measurements
x,y,w,h = cv2.boundingRect(c)
# Find measurements
diameter = w
radius = w/2
# Find centroid
M = cv2.moments(c)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
# Draw the contour and center of the shape on the image
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),4)
cv2.drawContours(image,[c], 0, (36,255,12), 4)
cv2.circle(image, (cX, cY), 15, (320, 159, 22), -1)
# Draw line and diameter information
cv2.line(image, (x, y + int(h/2)), (x + w, y + int(h/2)), (156, 188, 24), 3)
cv2.putText(image, "Diameter: {}".format(diameter), (cX - 50, cY - 50), cv2.FONT_HERSHEY_SIMPLEX, 3, (156, 188, 24), 3)
cv2.imwrite('...', image)
cv2.imwrite('...', thresh)
cv2.imwrite('...', opening)
I had already tried by measuring the size of an object (in inches) with Known width of a reference object .I am done by referring this link https://www.pyimagesearch.com/2016/03/28/measuring-size-of-objects-in-an-image-with-opencv/. But I don't know how to detect circle object and find the diameter of the object using OpenCV in python.Please,help me Thanks in Advance.
Here is my code:
if pixelsPerMetric is None:
pixelsPerMetric = dB / 8.070866
dimA = dA / pixelsPerMetric
dimB = dB / pixelsPerMetric
print("dd",dimA,dimB)
# draw the object sizes on the image
cv2.putText(orig, "{:.4f}in".format(dimA),
(int(tltrX - 15), int(tltrY - 10)), cv2.FONT_HERSHEY_SIMPLEX,
0.65, (255, 0, 255), 2)
cv2.putText(orig, "{:.4f}in".format(dimB),
(int(trbrX + 10), int(trbrY)), cv2.FONT_HERSHEY_SIMPLEX,
0.65, (255, 0, 255), 2)
cv2.imshow("Image", orig)
cv2.waitKey(0)
Does a hough circle transform would fit your needs ?
-> see here
Regards,
in this example I am drawing some line elements 30px away from the origin in the Y coordinate while moving along he X coordinate. This is drawn on a recording surface because in my real code I don't know the extend before I start. After drawing is done I repeat the drawing on the PDFSurface but since I want my PDF and PNG to end flush with my drawn elements I set the boundaries of the PDFSurface to the height and width of the ink_extents of the RecordingSurface. Next because I was drawing 30px lower with only empty space above I translate my drawing in set_source_surface -30px. Now when writing the PNG all works fine but the PDF is empty. If I extend the height to 100px manually the PDF is drawn correctly with the correct origin. If I start drawing at Y 0px instead of Y 30px it also works. Do I miss anything or is it a bug?
Thanks for your help. Here is a test code:
import cairocffi as cairo
rs = cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, None)
ctxRS = cairo.Context(rs)
items = ([0], [28, 29], [39], [42], [64], [67], [70, 71, 72], [76, 77], [79, 80], [86], [90], [104, 105],
[131], [134, 135, 136, 137, 138, 139], [145, 146, 147], [150, 151], [156], [174], [188], [191],
[199, 200], [203], [212], [216], [229, 230], [240, 241, 242, 243], [262])
for item in items:
initialPosition = item[0]
numberOfItems = len(item)
offset = initialPosition * 10
lineLength = 10 * numberOfItems
ctxRS.set_source_rgba(1.0, 0.0, 0.0, 1.0)
ctxRS.set_line_width(0)
ctxRS.move_to(offset, 30)
ctxRS.line_to(offset, 40)
ctxRS.line_to(offset + lineLength, 40)
ctxRS.line_to(offset + lineLength, 30)
ctxRS.close_path()
ctxRS.stroke_preserve()
ctxRS.set_source_rgba(1.0, 0.0, 0.0, 1.0)
ctxRS.fill()
x, y, width, height = rs.ink_extents()
ps = cairo.PDFSurface("cairoTest.pdf", width, height)
ctxPS = cairo.Context(ps)
ctxPS.set_source_surface(rs, -x, -y)
ctxPS.paint()
ps.write_to_png("cairoTest.png")
ps.finish()