Related
How can I change the extent of a series of images?
Let's say we have (0, 100, 0, 200, 0, 300). I just want to change to (0, 200, 0, 100, 0, 300). It seems like rotate the volume.
Cheers
In order to draw a graph I have defined the pos as a dictionary:
pos={'0025': (0, 0), '0023': (400, 0), '0028': (800, 0), '0029': (1200, 0), '0045': (1600, 0), '0057': (2000, 0), '0062': (2400, 0), '0083': (2800, 0), '0107': (3200, 0), '0111': (3600, 0), '0141': (4000, 0), '0144': (4400, 0), '0026': (800.0, 1), '0050': (1200.0, 1), '0115': (2600.0, 1)}
But I do not get the nodes represented where I expected:
Notice that the relative position is OK but the scale is not right. Probably I am misunderstanding something.
Here is the code I wrote to draw the graph:
def draw_G_msn_tr(self):
pos={'0025': (0, 0), '0023': (400, 0), '0028': (800, 0), '0029': (1200, 0), '0045': (1600, 0), '0057': (2000, 0), '0062': (2400, 0), '0083': (2800, 0), '0107': (3200, 0), '0111': (3600, 0), '0141': (4000, 0), '0144': (4400, 0), '0026': (800.0, 1), '0050': (1200.0, 1), '0115': (2600.0, 1)}
nx.draw(self.G_msn_tr,pos=pos, node_color=self.node_colors, with_labels=True, node_size=900)
plt.axis("off")
plt.show()
I need more space between nodes in order to show edge labels
Thank you in advance for your support.
BR.
I am following the tutorial available in https://pythonprogramming.net/opengl-pyopengl-python-pygame-tutorial/ where he teachs how to render a cube with pyOpenGL an pygame.
When rendering the cube, the tutorial set color to all the vertices of the cubes and then dispays it. However, im my project, i load object from a .obj file using the code provided in https://www.pygame.org/wiki/OBJFileLoader and most of my objects is fully white.
Conclusion: when i render it on screen, i only see full white, which is very ugly. So i tought to use a light to better view the object, but i cannot make this work.
I know very little of pyOpenGl and i cannot find a deeper tutorial of it.
Here is part of the code and the result provided in the tutorial. (vertices, edges, surfaces and color variables are tuple of tuples)
def Cube():
glBegin(GL_QUADS)
for surface in surfaces:
x = 0
for vertex in surface:
x+=1
glColor3fv(colors[x])
glVertex3fv(verticies[vertex])
glEnd()
glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(verticies[vertex])
glEnd()
def main():
pygame.init()
display = (800,600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
glTranslatef(0.0,0.0, -5)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glRotatef(1, 3, 1, 1)
Cube()
pygame.display.flip()
pygame.time.wait(10)
main()
i tried to edit the main function to insert a simple light, but the colors in the cube just disapeared:
def main():
pygame.init()
display = (800,600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
glTranslatef(0.0,0.0, -5)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glRotatef(1, 3, 1, 1)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glPushMatrix()
glTranslatef(0.0,0.0, 5)
glLight(GL_LIGHT0, GL_POSITION, (0, 1, 0, 1))
glLightfv(GL_LIGHT0, GL_AMBIENT, (0, 1.5, 1, 0))
glPopMatrix()
Cube()
glDisable(GL_LIGHT0)
glDisable(GL_LIGHTING)
pygame.display.flip()
pygame.time.wait(10)
What i want is the cube with its colors and iluminated by a light. What is wrong with my code and how to fix it?
When lighting (GL_LIGHTING) is enabled, then the color is taken from the material parameters (glMaterial).
If you still want to use the current color, the you have to enable GL_COLOR_MATERIAL
and to set the color material paramters (glColorMaterial).
The ambient light does not depend on the the direction of the light source. You've to define a diffuse and/or specular light. See glLightfv:
When the light position is set by glLightfv(GL_LIGHT0, GL_POSITION, pos), then the position is multiplied by the current model view matrix. So the light position in world space has to be set before the model transformation.
Switch to the matrix mode GL_PROJECTION, before the projection matrix is set. Otherwise the light position would be multiplied by the projection matrix.
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0, 0, -5)
#glLight(GL_LIGHT0, GL_POSITION, (0, 0, 1, 0)) # directional light from the front
glLight(GL_LIGHT0, GL_POSITION, (5, 5, 5, 1)) # point light from the left, top, front
glLightfv(GL_LIGHT0, GL_AMBIENT, (0, 0, 0, 1))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (1, 1, 1, 1))
glEnable(GL_DEPTH_TEST)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE )
glRotatef(1, 3, 1, 1)
Cube()
glDisable(GL_LIGHT0)
glDisable(GL_LIGHTING)
glDisable(GL_COLOR_MATERIAL)
pygame.display.flip()
The diffuse (and specular) light depends on the Normal vector of the surface.
Define an array of normal vector tuples (x, y, z). Note the following definition is an example. Since you draw a cube, which has 6 faces, you've to define 6 normal vectors, but the direction of the vectors depends on your vertex coordinates, which I do not know.
normals = [
( 0, 0, -1), # surface 0
(-1, 0, 0), # surface 1
( 0, 1, 1), # surface 2
( 1, 0, 0), # surface 3
( 0, 1, 0), # surface 4
( 0, -1, 0) # surface 5
]
And set the proper normal vector when the object is drawn:
def Cube():
glBegin(GL_QUADS)
for i_surface, surface in enumerate(surfaces):
x = 0
glNormal3fv(normals[i_surface]) # set the normal vector the vertices of the surface
for vertex in surface:
x+=1
glColor3fv(colors[x])
glVertex3fv(verticies[vertex])
glEnd()
glColor3fv(colors[0])
glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(verticies[vertex])
glEnd()
Enable the Depth Test (glEnable(GL_DEPTH_TEST)) to get an animation like the following:
Full example code:
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
verticies = (
( 1, -1, -1), # 0
( 1, 1, -1), # 1
(-1, 1, -1), # 2
(-1, -1, -1), # 3
( 1, -1, 1), # 4
( 1, 1, 1), # 5
(-1, -1, 1), # 6
(-1, 1, 1), # 7
)
surfaces = (
(0,1,2,3),
(3,2,7,6),
(6,7,5,4),
(4,5,1,0),
(1,5,7,2),
(4,0,3,6),
)
normals = [
( 0, 0, -1), # surface 0
(-1, 0, 0), # surface 1
( 0, 0, 1), # surface 2
( 1, 0, 0), # surface 3
( 0, 1, 0), # surface 4
( 0, -1, 0) # surface 5
]
colors = (
(1,1,1),
(0,1,0),
(0,0,1),
(0,1,0),
(0,0,1),
(1,0,1),
(0,1,0),
(1,0,1),
(0,1,0),
(0,0,1),
)
edges = (
(0,1),
(0,3),
(0,4),
(2,1),
(2,3),
(2,7),
(6,3),
(6,4),
(6,7),
(5,1),
(5,4),
(5,7),
)
def Cube():
glBegin(GL_QUADS)
for i_surface, surface in enumerate(surfaces):
x = 0
glNormal3fv(normals[i_surface])
for vertex in surface:
x+=1
glColor3fv(colors[x])
glVertex3fv(verticies[vertex])
glEnd()
glColor3fv(colors[0])
glBegin(GL_LINES)
for edge in edges:
for vertex in edge:
glVertex3fv(verticies[vertex])
glEnd()
def main():
global surfaces
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
clock = pygame.time.Clock()
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
glMatrixMode(GL_MODELVIEW)
glTranslatef(0, 0, -5)
#glLight(GL_LIGHT0, GL_POSITION, (0, 0, 1, 0)) # directional light from the front
glLight(GL_LIGHT0, GL_POSITION, (5, 5, 5, 1)) # point light from the left, top, front
glLightfv(GL_LIGHT0, GL_AMBIENT, (0, 0, 0, 1))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (1, 1, 1, 1))
glEnable(GL_DEPTH_TEST)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE )
glRotatef(1, 3, 1, 1)
Cube()
glDisable(GL_LIGHT0)
glDisable(GL_LIGHTING)
glDisable(GL_COLOR_MATERIAL)
pygame.display.flip()
clock.tick(60)
main()
I already have the code to find the contours of hand and to find the extreme points of the of the contour.
Now I want to find the fingertips of the hand for that the only approach comes to my mind is the local maxima technique but I don't know how to find these.
# import the necessary packages
import imutils
import cv2
# load the image, convert it to grayscale, and blur it slightly
image = cv2.imread("hand.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
# threshold the image, then perform a series of erosions +
# dilations to remove any small regions of noise
thresh = cv2.threshold(gray, 45, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=2)
# find contours in thresholded image, then grab the largest
# one
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)
# determine the most extreme points along the contour
extLeft = tuple(c[c[:, :, 0].argmin()][0])
extRight = tuple(c[c[:, :, 0].argmax()][0])
extTop = tuple(c[c[:, :, 1].argmin()][0])
extBot = tuple(c[c[:, :, 1].argmax()][0])
# draw the outline of the object, then draw each of the
# extreme points, where the left-most is red, right-most
# is green, top-most is blue, and bottom-most is teal
cv2.drawContours(image, [c], -1, (0, 255, 255), 2)
cv2.circle(image, extLeft, 8, (0, 0, 255), -1)
cv2.circle(image, extRight, 8, (0, 255, 0), -1)
cv2.circle(image, extTop, 8, (255, 0, 0), -1)
cv2.circle(image, extBot, 8, (255, 255, 0), -1)
# show the output image
cv2.imshow("Image", image)
cv2.waitKey(0)
Example image:
How do I pass a line through the center of a contour? I have the center coordinates of my contour.
This is how you solve this question -
Original image -
Result image -
You first need to do basic filtering and find the contour. Then -
1) Find out the area of contour (minAreaRect)
2) Extract points from the contour (BoxPoints)
3) Convert it to a numpy array (np.array)
4) Order the points (perspective.order_points)
5) Take out Top-left, Top-right, Bottom-right and Bottom-left(tl, tr, br, bl) = box (Line 52)
6) Calculate the midpoints ( (point1 + point2) / 2)
7) Draw the lines (line 76)
Here is the code for it
# import the necessary packages
from scipy.spatial import distance as dist
from imutils import perspective
from imutils import contours
import numpy as np
import imutils
import cv2
# Method to find the mid point
def midpoint(ptA, ptB):
return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)
# load the image, convert it to grayscale, and blur it slightly
image = cv2.imread("test.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (7, 7), 0)
# perform edge detection, then perform a dilation + erosion to
# close gaps in between object edges
edged = cv2.Canny(gray, 50, 100)
edged = cv2.dilate(edged, None, iterations=1)
edged = cv2.erode(edged, None, iterations=1)
# find contours in the edge map
cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
# loop over the contours individually
for c in cnts:
# This is to ignore that small hair countour which is not big enough
if cv2.contourArea(c) < 1000:
continue
# compute the rotated bounding box of the contour
box = cv2.minAreaRect(c)
box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)
box = np.array(box, dtype="int")
# order the points in the contour such that they appear
# in top-left, top-right, bottom-right, and bottom-left
# order, then draw the outline of the rotated bounding
# box
box = perspective.order_points(box)
# draw the contours on the image
orig = image.copy()
cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 3)
# unpack the ordered bounding box, then compute the midpoint
# between the top-left and top-right coordinates, followed by
# the midpoint between bottom-left and bottom-right coordinates
(tl, tr, br, bl) = box
(tltrX, tltrY) = midpoint(tl, tr)
(blbrX, blbrY) = midpoint(bl, br)
# compute the midpoint between the top-left and top-right points,
# followed by the midpoint between the top-righ and bottom-right
(tlblX, tlblY) = midpoint(tl, bl)
(trbrX, trbrY) = midpoint(tr, br)
# draw and write the midpoints on the image
cv2.circle(orig, (int(tltrX), int(tltrY)), 5, (255, 0, 0), -1)
cv2.putText(orig, "({},{})".format(tltrX, tltrY), (int(tltrX - 50), int(tltrY - 10) - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 2)
cv2.circle(orig, (int(blbrX), int(blbrY)), 5, (255, 0, 0), -1)
cv2.putText(orig, "({},{})".format(blbrX, blbrY), (int(blbrX - 50), int(blbrY - 10) - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 2)
cv2.circle(orig, (int(tlblX), int(tlblY)), 5, (255, 0, 0), -1)
cv2.putText(orig, "({},{})".format(tlblX, tlblY), (int(tlblX - 50), int(tlblY - 10) - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 2)
cv2.circle(orig, (int(trbrX), int(trbrY)), 5, (255, 0, 0), -1)
cv2.putText(orig, "({},{})".format(trbrX, trbrY), (int(trbrX - 50), int(trbrY - 10) - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 2)
# draw lines between the midpoints
cv2.line(orig, (int(tltrX), int(tltrY)), (int(blbrX), int(blbrY)),
(255, 0, 255), 2)
cv2.line(orig, (int(tlblX), int(tlblY)), (int(trbrX), int(trbrY)),
(255, 0, 255), 2)
# compute the Euclidean distance between the midpoints
dA = dist.euclidean((tltrX, tltrY), (blbrX, blbrY))
dB = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))
# loop over the original points
for (xA, yA) in list(box):
# draw circles corresponding to the current points and
cv2.circle(orig, (int(xA), int(yA)), 5, (0,0,255), -1)
cv2.putText(orig, "({},{})".format(xA, yA), (int(xA - 50), int(yA - 10) - 20),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,0,0), 2)
# show the output image, resize it as per your requirements
cv2.imshow("Image", orig)
cv2.waitKey(0)