How to write beta with PIL in python? - python-3.x

How to write beta with PIL in python?
I tried:
draw.multiline_text((350, 300), 'β', fill=(0, 0, 0), font = font_small)
draw.multiline_text((350, 300), r'$\beta$', fill=(0, 0, 0), font = font_small)
draw.multiline_text((350, 300), u'ß', fill=(0, 0, 0), font = font_small)
draw.multiline_text((350, 300), u'\u03B2', fill=(0, 0, 0), font = font_small)
draw.multiline_text((350, 300), u"ß", fill=(0, 0, 0), font = font_small)

Related

Cropping an ROI in image

I am trying to crop ROI in an image. I have the bounding box coordinates, but I don't understand how to use it to extract sub-array from the original image
Here's a snippet of my code:
`for j, box in enumerate(draw_boxes):
cv2.rectangle(orig_image,
(int(box[0]), int(box[1])),
(int(box[2]), int(box[3])),
(0, 0, 255), 2)
cv2.putText(orig_image, pred_classes[j],
(int(box[0]), int(box[1]-5)),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0),
2, lineType=cv2.LINE_AA)
print(box[0], box[1], box[2], box[3])
cropped = orig_image[int(box[0]): int(box[1]), int(box[2]): int(box[3])]
cv2.imwrite(f"../test_predictions/{image_name}.jpg", orig_image)
cv2.imshow('Cropped', cropped)
cv2.imshow('Prediction', orig_image)
cv2.waitKey()`

Threads for 4(or more) concurrent array sorts

I create a code that just sorts the same array into 4 windows:
import pygame
pygame.init()
win = pygame.display.set_mode((800, 600))
canvas = pygame.Surface((800, 600))
p1_camera = pygame.Rect(0,0,400,300)
p2_camera = pygame.Rect(400,0,400,300)
p3_camera = pygame.Rect(0,300,400,300)
p4_camera = pygame.Rect(400,300,400,300)
sub1 = canvas.subsurface(p1_camera)
sub2 = canvas.subsurface(p2_camera)
sub3 = canvas.subsurface(p3_camera)
sub4 = canvas.subsurface(p4_camera)
pygame.draw.line(sub2, (255,255,255), (0,0), (0,300), 10)
pygame.draw.line(sub4, (255,255,255), (0,0), (0,300), 10)
pygame.draw.line(sub3, (255,255,255), (0,0), (400,0), 10)
pygame.draw.line(sub4, (255,255,255), (0,0), (400,0), 10)
pygame.display.set_caption("Bubble sort")
x = 40
y = 40
width = 20
height = [3, 50, 130, 90, 250, 61, 110,
88, 33, 80, 70, 159, 180, 20]
run = True
def show(height):
for i in range(len(height)):
pygame.draw.rect(sub1, (255, 0, 0), (x + 25 * i, y, width, height[i]))
pygame.draw.rect(sub2, (255, 0, 0), (x + 25 * i, y, width, height[i]))
pygame.draw.rect(sub3, (255, 0, 0), (x + 25 * i, y, width, height[i]))
pygame.draw.rect(sub4, (255, 0, 0), (x + 25 * i, y, width, height[i]))
pygame.draw.line(sub2, (255,255,255), (0,0), (0,300), 10)
pygame.draw.line(sub4, (255,255,255), (0,0), (0,300), 10)
pygame.draw.line(sub3, (255,255,255), (0,0), (400,0), 10)
pygame.draw.line(sub4, (255,255,255), (0,0), (400,0), 10)
win.blit(sub1, (0,0))
win.blit(sub2, (400, 0))
win.blit(sub3, (0, 300))
win.blit(sub4, (400, 300))
while run:
execute = False
pygame.time.delay(10)
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if keys[pygame.K_SPACE]:
execute = True
if execute == False:
win.fill((0, 0, 0))
show(height)
pygame.display.update()
else:
for i in range(len(height) - 1):
for j in range(len(height) - i - 1):
if height[j] > height[j + 1]:
t = height[j]
height[j] = height[j + 1]
height[j + 1] = t
sub1.fill((0, 0, 0))
sub2.fill((0, 0, 0))
sub3.fill((0, 0, 0))
sub4.fill((0, 0, 0))
show(height)
pygame.time.delay(50)
pygame.display.update()
pygame.quit()
It works fine, but my main task was to create parallel sorting threads of different arrays. But I can't imagine how to do it in pygame, because the update goes to the whole window, not just part of it.
I will be grateful for advice or help.
The pygame.display.update() method has an optional argument that allowes you to only update part of the screen. https://www.pygame.org/docs/ref/display.html#pygame.display.update
You can define a rect that will be the only area updated.
You also tagged your question with multi threading, which can be done using this library: https://docs.python.org/3/library/threading.html
This should be everything you need.

Calculate the number of conenected pixels of a particular value in Numpy/OpenCV

def get_area(center_x: int, center_y: int, mask: np.ndarray) -> int:
if mask[center_x][center_y] != 255:
return -1
return ...
Now I got this function above that takes in a value for the x and y and finds the number of pixels that are connected to this pixel with the value of 255.
Now let's say, I have a simple np.ndarray that looks like this:
[
[255,255, 0, 0, 0, 0, 0,255,255],
[255, 0, 0,255,255,255, 0, 0,255],
[ 0, 0,255, 0, 0, 0,255, 0, 0],
[ 0,255, 0, 0,255, 0, 0,255, 0],
[ 0,255, 0,255,255,255, 0,255, 0],
[ 0,255, 0, 0,255, 0, 0,255, 0],
[ 0, 0,255, 0, 0, 0,255, 0, 0],
[255, 0, 0,255,255,255, 0, 0,255],
[255,255, 0, 0, 0, 0, 0,255,255]
]
If I took the center pixel of 255 as an input, the output of the function I am trying to build will be 5, since there are 4 neighboring pixels that are 255s.
I am amenable to using both opencv and numpy, but np is more preferable.
from PIL import Image
import numpy as np
from scipy import ndimage
imgMtx = [
[255,255, 0, 0, 0, 0, 0,255,255],
[255, 0, 0,255,255,255, 0, 0,255],
[ 0, 0,255, 0, 0, 0,255, 0, 0],
[ 0,255, 0, 0,255, 0, 0,255, 0],
[ 0,255, 0,255,255,255, 0,255, 0],
[ 0,255, 0, 0,255, 0, 0,255, 0],
[ 0, 0,255, 0, 0, 0,255, 0, 0],
[255, 0, 0,255,255,255, 0, 0,255],
[255,255, 0, 0, 0, 0, 0,255,255]
]
img = Image.fromarray(np.asarray(imgMtx))
blobs = np.asarray(img) > 125
labels, nlabels = ndimage.label(blobs)
unique, counts = np.unique(labels, return_counts=True)
import numpy as np
def get_area(center_x: int, center_y: int, mask: np.ndarray) -> int:
"""
Basic flood-fill area calculation on the mask using Breadth First Search
"""
area = 0
moves = [(1, 1), (0, 1), (1, 0), (-1, -1), (0, -1), (-1, 0), (-1, 1), (1, -1)]
if mask[center_x][center_y] != 255:
return -1
visited = [[False for _ in range(mask.shape[0])] for _ in range(mask.shape[1])]
q = deque()
q.append((center_x, center_y))
visited[center_x][center_y] = True
while q:
x, y = q.popleft()
for move in moves:
if (x + move[0] >= mask.shape[0] or y + move[1] >= mask.shape[1] or
x + move[0] < 0 or y + move[1] < 0):
continue
if mask[x + move[0]][y + move[1]] == 255 and not visited[x + move[0]][y + move[1]]:
area += 1
q.append((x + move[0], y + move[1]))
visited[x + move[0]][y + move[1]] = True
return area
Decided to code an answer by myself and made a breadth first search floodfill algorithm on the supplied mask.

Python OpenGL Texture wont properly load

This is my program:
import glfw
from OpenGL.GL import *
import OpenGL.GL.shaders
import numpy
from PIL import Image
def main():
# initialize glfw
if not glfw.init():
return
# creating the window
window = glfw.create_window(800, 600, "My OpenGL window", None, None)
if not window:
glfw.terminate()
return
glfw.make_context_current(window)
# positions colors texture coords
quad = [-0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
-0.5, 0.5, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0]
quad = numpy.array(quad, dtype=numpy.float32)
indices = [0, 1, 2,
2, 3, 0]
indices = numpy.array(indices, dtype=numpy.uint32)
vertex_shader = """
#version 330
in layout(location = 0) vec3 position;
in layout(location = 1) vec3 color;
in layout(location = 2) vec2 inTexCoords;
out vec3 newColor;
out vec2 outTexCoords;
void main()
{
gl_Position = vec4(position, 1.0f);
newColor = color;
outTexCoords = inTexCoords;
}
"""
fragment_shader = """
#version 330
in vec3 newColor;
in vec2 outTexCoords;
out vec4 outColor;
uniform sampler2D samplerTex;
void main()
{
outColor = texture(samplerTex, outTexCoords);
}
"""
shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(vertex_shader, GL_VERTEX_SHADER),
OpenGL.GL.shaders.compileShader(fragment_shader, GL_FRAGMENT_SHADER))
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, 128, quad, GL_STATIC_DRAW)
EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24, indices, GL_STATIC_DRAW)
# position = glGetAttribLocation(shader, "position")
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
glEnableVertexAttribArray(0)
# color = glGetAttribLocation(shader, "color")
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
glEnableVertexAttribArray(1)
# texCoords = glGetAttribLocation(shader, "inTexCoords")
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
glEnableVertexAttribArray(2)
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)
# texture wrapping params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# texture filtering params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
image = Image.open("res/crate.jpg")
img_data = numpy.array(list(image.getdata()), numpy.uint8)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 420, 420, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
glUseProgram(shader)
glClearColor(0.2, 0.3, 0.2, 1.0)
while not glfw.window_should_close(window):
glfw.poll_events()
glClear(GL_COLOR_BUFFER_BIT)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
glfw.swap_buffers(window)
glfw.terminate()
if __name__ == "__main__":
main()
Expectation:
Result:
Help.
After loading the image, the format of the image is 'JPEG'.
You have to convert the image to the format RGB
image = image.convert('RGB')
and to flip the image top to bottom:
image = image.transpose(Image.FLIP_TOP_BOTTOM)
Before you load the image you have to set the the GL_UNPACK_ALIGNMENT to 1 by glPixelStorei, because the length of the lines of the image is not aligned to 4:
image = Image.open("res/crate.jpg")
image = image.convert('RGB')
image = image.transpose(Image.FLIP_TOP_BOTTOM)
img_data = numpy.array(list(image.getdata()), numpy.uint8)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 420, 420, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
Of course you can use the format RGBA too:
image = Image.open("res/crate.jpg")
image = image.convert('RGBA')
image = image.transpose(Image.FLIP_TOP_BOTTOM)
img_data = numpy.array(list(image.getdata()), numpy.uint8)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 420, 420, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)
image = Image.open("res/crate.jpg")
image = image.convert('RGB')
image = image.transpose(Image.FLIP_TOP_BOTTOM)
img_data = np.array(list(image.getdata()), np.uint8)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 420, 420, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
#image = Image.open("res/crate.jpg")
#image = image.convert('RGBA')
#image = image.transpose(Image.FLIP_TOP_BOTTOM)
#img_data = np.array(list(image.getdata()), np.uint8)
#glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 420, 420, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)
both of those methods fix my problem so thanks for everyone who helped

Tkinter, Draughts board

I'd like to create a Draughts' game board.
At first, Everything worked fine while I was drawing squares and pawns directly on the "board" canvas. As I have to manipulate those pawns afterward, I wanted it to be more explicite by creating each square and pawn as objects.
So I tried to create a Board which will contain black or white square which will contain circles (the pawns). Then everything, messed up. I don't know why. Even so it looks perfectly logical (for me).
I think it is related to the use of the pack method.
Here's the code :
from tkinter import *
class Parent(Tk):
def getRoot(self):
return(self.body)
def setTitle(self,title):
self.title(title)
def run(self):
self.mainloop()
class Drawing:
def __init__(self,root,width,height):
self.zone=Canvas(root, width=width, height=height)
def put(self,root,row,col):
self.zone.grid(root,row=row,column=col)
def getDrawing(self):
return(self.zone)
def rectangle(self,coordX1,coordY1,coordX2,coordY2,color):
self.zone.create_rectangle(coordX1,coordY1,coordX2,coordY2,fill=color, outline="black")
def circle(self,coordX1,coordY1,coordX2,coordY2,color):
self.zone.create_oval(coordX1,coordY1,coordX2,coordY2,fill=color,outline="black")
if __name__=="__main__":
root=Parent()
root.setTitle("Draughts")
board=Drawing(root,400,400)
size=40
logicBoard=[[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]]
DIMENSION=10
for i in range(DIMENSION):
for j in range(DIMENSION):
coordX1 = (i * size)
coordY1 = (j * size)
coordX2 = coordX1 + size
coordY2 = coordY1 + size
if(not(i%2==j%2)):#if the square is black (on the board)
color="black"
else:
color="white"
case=Drawing(board.getDrawing(),40,40)
case.rectangle(coordX1,coordY1,coordX2,coordY2,color)
case.getDrawing().pack()
if(logicBoard[i][j]>0):
pawnColor="white"
elif(logicBoard[i][j]<0):
pawnColor="black"
if (not(i%2==j%2)):
pawn=Drawing(case.getDrawing(),40,40)
pawn.circle(0,0,30,30,pawnColor)
pawn.getDrawing().pack()
board.getDrawing().pack()
root.run()
Thank you !
EDIT:
This is what I get :
The problem is that you create a new Canvas and call pack() on it in each iteration, instead of using the one you create at the beginning. In the end, you are using the class Drawing to create new Drawings. I suggest you to use only one class to represent all the board, with the methods to draw the squares and the circles.
I've changed the colors of the ovals to have a better contrast:
from tkinter import Tk, Canvas
from itertools import product
class Board(Tk):
def __init__(self, width, height, cellsize):
Tk.__init__(self)
self.cellsize = cellsize
self.canvas = Canvas(self, width=width, height=height)
self.canvas.bind("<Button-1>", self.onclick)
self.canvas.pack()
def draw_rectangle(self, x1, y1, x2, y2, color):
self.canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline="black")
def draw_circle(self, x1, y1, x2, y2, color):
self.canvas.create_oval(x1, y1, x2, y2, fill=color, outline="black")
def onclick(self, event):
i = int(event.x / self.cellsize)
j = int(event.y / self.cellsize)
print "You clicked on cell (%s, %s)" % (i, j)
if __name__=="__main__":
size = 40
board = Board(400, 400, size)
board.title("Draughts")
logicBoard = [[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, -1, 0, -1, 0, -1, 0, -1, 0, -1],
[-1, 0, -1, 0, -1, 0, -1, 0, -1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]]
for (i, j) in product(range(10), range(10)):
coordX1 = (i * size)
coordY1 = (j * size)
coordX2 = coordX1 + size
coordY2 = coordY1 + size
color = "white" if i%2 == j%2 else "black"
board.draw_rectangle(coordX1, coordY1, coordX2, coordY2, color)
cell = logicBoard[i][j]
if cell != 0:
pawnColor = "red" if cell > 0 else "blue"
board.draw_circle(coordX1, coordY1, coordX2, coordY2, pawnColor)
board.mainloop()
Edit:
If you want to keep track of the clicks, it is clearer and simpler to bind a handler function to the canvas and calculate the point, instead of creating lots of canvas with their own event handler.

Resources