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 am using Pyqt5 to plot some medical images (numpy arrays) in three different widgets. Now, I want to plot a line over the image (displayed using pg.ImageViewer). Have someone already done this?
Thanks!
You can access the viewbox of the pg.ImageView widget using .getView(). From there you can add any items to it that you like using viewbox.AddItem(). Below is a modified version of the ImageView example which plots a line plot on the ImageView.
# -*- coding: utf-8 -*-
"""
This example demonstrates the use of ImageView with 3-color image stacks.
ImageView is a high-level widget for displaying and analyzing 2D and 3D data.
ImageView provides:
1. A zoomable region (ViewBox) for displaying the image
2. A combination histogram and gradient editor (HistogramLUTItem) for
controlling the visual appearance of the image
3. A timeline for selecting the currently displayed frame (for 3D data only).
4. Tools for very basic analysis of image data (see ROI and Norm buttons)
"""
## Add path to library (just for examples; you do not need this)
import initExample
import numpy as np
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
# Interpret image data as row-major instead of col-major
pg.setConfigOptions(imageAxisOrder='row-major')
app = pg.mkQApp("ImageView Example")
## Create window with ImageView widget
win = QtGui.QMainWindow()
win.resize(800,800)
imv = pg.ImageView()
imv_v = imv.getView()
win.setCentralWidget(imv)
win.show()
win.setWindowTitle('pyqtgraph example: ImageView')
## Create random 3D data set with time varying signals
dataRed = np.ones((100, 200, 200)) * np.linspace(90, 150, 100)[:, np.newaxis, np.newaxis]
dataRed += pg.gaussianFilter(np.random.normal(size=(200, 200)), (5, 5)) * 100
dataGrn = np.ones((100, 200, 200)) * np.linspace(90, 180, 100)[:, np.newaxis, np.newaxis]
dataGrn += pg.gaussianFilter(np.random.normal(size=(200, 200)), (5, 5)) * 100
dataBlu = np.ones((100, 200, 200)) * np.linspace(180, 90, 100)[:, np.newaxis, np.newaxis]
dataBlu += pg.gaussianFilter(np.random.normal(size=(200, 200)), (5, 5)) * 100
data = np.concatenate(
(dataRed[:, :, :, np.newaxis], dataGrn[:, :, :, np.newaxis], dataBlu[:, :, :, np.newaxis]), axis=3
)
## Display the data and assign each frame a time value from 1.0 to 3.0
imv.setImage(data, xvals=np.linspace(1., 3., data.shape[0]))
'''ADDED CODE'''
imv_v = imv.getView()
pci = pg.PlotCurveItem(x=[1,50,100,150,200], y=[1,50,100,150,200])
imv_v.addItem(pci)
''''''
## Set a custom color map
colors = [
(0, 0, 0),
(45, 5, 61),
(84, 42, 55),
(150, 87, 60),
(208, 171, 141),
(255, 255, 255)
]
cmap = pg.ColorMap(pos=np.linspace(0.0, 1.0, 6), color=colors)
imv.setColorMap(cmap)
# Start up with an ROI
imv.ui.roiBtn.setChecked(True)
imv.roiClicked()
if __name__ == '__main__':
pg.exec()
I tried to mask image by its color using opencv.
import cv2
import numpy as np
import matplotlib.pyplot as plt
After importing libraries, I load the image
img = cv2.imread('gmaps.jpg')
image = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(image);
Turn the color into hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
plt.imshow(hsv);
Masking process
low_orange = np.array([44, 6, 100])
high_orange = np.array([44, 24, 99])
masking = cv2.inRange(hsv,low_orange, high_orange)
plt.imshow(masking);
The result isn't what I expected.
Image :
Result :
EDIT: I want to mask the building only. Instead I got the result of masking all of the frame.
Using my answer from here I manage to extract the right values for you
Code:
frame = cv2.imread("Xv6gx.png")
blurred_frame = cv2.GaussianBlur(frame, (5, 5), 0)
hsv = cv2.cvtColor(blurred_frame, cv2.COLOR_BGR2HSV)
lower = np.array([4, 0, 7])
upper = np.array([87, 240, 255])
mask = cv2.inRange(hsv, lower, upper)
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
for contour in contours:
area = cv2.contourArea(contour)
if area > 5000:
# -- Draw Option 1 --
cv2.drawContours(frame, contour, -1, (0, 255, 0), 3)
# -- Draw Option 2--
# rect = cv2.boundingRect(contour)
# x, y, w, h = rect
# cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Mask", mask)
cv2.imshow("Frame", frame)
cv2.waitKey(0)
Final Results:
I wouldn't expect the low Value (100) to exceed the high Value (99).
Also, OpenCV uses a range of 0..180 for Hue rather than 0..360, so you likely need to divide your 44 by 2.
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)
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,