grabscreen.py Python win32api - linux

Any Linux or Mac OS equivalent libraries to Win32gui, or to this code ?
working on an outside project and this windows code will help me grab the screen. Havent been able to find any libraries that are similar. Thank you
def grab_screen(region=None):
hwin = win32gui.GetDesktopWindow()
if region:
left,top,x2,y2 = region
width = x2 - left + 1
height = y2 - top + 1
else:
width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
hwindc = win32gui.GetWindowDC(hwin)
srcdc = win32ui.CreateDCFromHandle(hwindc)
memdc = srcdc.CreateCompatibleDC()
bmp = win32ui.CreateBitmap()
bmp.CreateCompatibleBitmap(srcdc, width, height)
memdc.SelectObject(bmp)
memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY)
signedIntsArray = bmp.GetBitmapBits(True)
img = np.fromstring(signedIntsArray, dtype='uint8')
img.shape = (height,width,4)
srcdc.DeleteDC()
memdc.DeleteDC()
win32gui.ReleaseDC(hwin, hwindc)
win32gui.DeleteObject(bmp.GetHandle())
return cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)

You can grab the screen with pyautogui:
import pyautogui
image = pyautogui.screenshot('filename.png')

You can do this :)
I think Mac OS can't use those WiIn32gui libraries.
instead you can use pillow for grabbing screen.
Screen size can be changed depends on the size you want.
import cv2
import numpy as np
import pyautogui
from PIL import ImageGrab
screen_w = 1920
screen_h = 1080
while True:
rgb = ImageGrab.grab(bbox=(0, 0, screen_w, screen_h))
rgb = np.array(rgb)
cv2.imshow('window_frame', rgb)
if cv2.waitKey(1) & 0xFF == ord('q'):
break

Related

Adding a border around Region of Interest using python

I have a code which takes images from a folder, crops the region of interest around it using the ROI function, and then removes the background using the rembg library. But I want a border around that image, around that specific object itself, like the one we get in segmentation, except keeping the colours and the object intact. [NOT A RECTANGULAR BORDER]. Can anyone help and tell me how to do it?
Here is my code for reference:
import cv2
import numpy as np
import os
from os.path import join
from os import listdir
from PIL import Image
from rembg import remove
path = 'Some path'
folder = 'Some other path'
count = 1
def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
if width is None and height is None:
return image
if width is None:
r = height / float(h)
dim = (int(w * r), height)
else:
r = width / float(w)
dim = (width, int(h * r))
resized = cv2.resize(image, dim, interpolation = inter)
return resized
for filename in os.listdir(folder):
img = cv2.imread(os.path.join(folder,filename))
if img is not None:
img = image_resize(img, height = 600)
roi = cv2.selectROI(img)
print(roi)
im_cropped = img[int(roi[1]):int(roi[1]+roi[3]),int(roi[0]):int(roi[0]+roi[2])]
rs = str(count)
rem = remove(im_cropped)
cv2.imshow("Removed Image", rem)
cv2.imwrite(os.path.join(path, rs + '.jpg'), rem)
count = count + 1
cv2.waitKey(0)
As i assume you mean a simple outline, i would suggest the following:
import cv2
import numpy as np
# Threshold the image
thresh = img > threshold
# Use binary dilation to widen the area
thresh_dil = cv2.dilate(thresh, np.ones((3, 3)) , iterations=1)
# Get the outlines by substracting the dilated image with the original area
outlines = thresh_dil - thresh
# Superimpose the outlines on your original image
img_with_outlines = img.copy()
img_with_outlines[outlines > 0] = 255
This should draw a white line around your detected object.
Note: This approach works grayscale images. For full colour images you can apply it for each channel individually.

I want to display images that are send to a specific folder in a sort of slideshow

I have a piece of code right now that when i start it up it creates a black canvas and displays a image on it (With Tkinter) that i randomly grab from a folder i have selected with photos in it.
But right now i have to press esc to go to the next image. I would like it to be on a timer.
It also won't go to the next image. It says pyimage2 does not exist.
It would be great if someone can help me. I am incredibly new to python and don't know that much.
from PIL import Image
import os, random
import time
import sys
if sys.version_info[0] == 2:
import Tkinter
tkinter = Tkinter
else:
import tkinter
from PIL import Image, ImageTk
i = True
def showPIL(pilImage):
root = tkinter.Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h))
root.focus_set()
root.bind("<Escape>", lambda e: (e.widget.withdraw(), e.widget.quit()))
canvas = tkinter.Canvas(root,width=w,height=h)
canvas.pack()
canvas.configure(background='black')
imgWidth, imgHeight = pilImage.size
if imgWidth > w or imgHeight > h:
ratio = min(w/imgWidth, h/imgHeight)
imgWidth = int(imgWidth*ratio)
imgHeight = int(imgHeight*ratio)
pilImage = pilImage.resize((imgWidth,imgHeight), Image.ANTIALIAS)
image = ImageTk.PhotoImage(pilImage)
imagesprite = canvas.create_image(w/2,h/2,image=image)
root.mainloop()
while i == True:
timer = 0
while timer < 5:
path = "C:/Users/thymen.hummel/PycharmProjects/HelloWorld/Images"
random_filename = random.choice([x
for x in os.listdir(path)
if os.path.isfile(os.path.join(path, x))
])
pilImage = Image.open(f'C:/Users/thymen.hummel/PycharmProjects/HelloWorld/Images/{random_filename}')
showPIL(pilImage)
print(random_filename)
timer += 1
time.sleep(5)
check https://www.geeksforgeeks.org/python-convert-speech-to-text-and-text-to-speech/. Instead of typing, you can name the name of the image and the program will open it.
To do it by timer, you can do it using pygame.time.wait(). It takes input in milliseconds. see https://www.pygame.org/docs/ref/time.html for more information.

How to draw arabic text on the image using `cv2.putText`correctly? (Python+OpenCV)

I use python cv2(window10, python3.6) to write text in the image, when the text is English it works, but when I use Arabic text it writes messy code in the image.
Below is my code:
import cv2
import numpy as np
blank_image = np.zeros((100,300,3), np.uint8)
font = cv2.FONT_HERSHEY_SIMPLEX
org = (10, 50)
fontScale = .5
color = (255, 0, 0)
thickness = 1
blank_image = cv2.putText(blank_image, "اللغة العربية", org, font,
fontScale, color, thickness, cv2.LINE_AA)
window_name = 'Image'
cv2.imshow(window_name, blank_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
the problem here
blank_image = cv2.putText(blank_image, "اللغة العربية", org, font,
fontScale, color, thickness, cv2.LINE_AA)
fontpath = "arial.ttf" # <== download font
font = ImageFont.truetype(fontpath, 32)
img_pil = Image.fromarray(frame)
draw = ImageDraw.Draw(img_pil)
draw.text((50, 80),'عربي', font = font)
img = np.array(img_pil)
cv2.imshow(window_name, img)
import cv2
import arabic_reshaper
from bidi.algorithm import get_display
import numpy as np
from PIL import ImageFont, ImageDraw, Image
cap = cv2.VideoCapture(0)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
text = "ذهب الطالب الى المدرسة"
reshaped_text = arabic_reshaper.reshape(text)
bidi_text = get_display(reshaped_text)
fontpath = "arial.ttf" # <== https://www.freefontspro.com/14454/arial.ttf
font = ImageFont.truetype(fontpath, 32)
img_pil = Image.fromarray(frame)
draw = ImageDraw.Draw(img_pil)
draw.text((50, 80),bidi_text, font = font)
img = np.array(img_pil)
cv2.imshow('window_name', img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
#before opening the programme
#first download arabic_reshaper lib write in Anaconda prompt
#"pip install arabic_reshaper"
#and download bidi lib write in Anaconda prompt
#"pip install python-bidi"
import arabic_reshaper
from bidi.algorithm import get_display
import numpy as np
from PIL import ImageFont, ImageDraw, Image
import cv2
img =cv2.imread("sun.jpg")
fontpath = "arial.ttf" # <== download font
font = ImageFont.truetype(fontpath, 32)
img_pil = Image.fromarray(img)
draw = ImageDraw.Draw(img_pil)
text="اللغة العربية"
reshaped_text = arabic_reshaper.reshape(text)
bidi_text = get_display(reshaped_text)
draw = ImageDraw.Draw(img_pil)
draw.text((50, 80),bidi_text, font = font)
img = np.array(img_pil)
cv2.imshow("image with arabic", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

PNG image that support scaling and changing transparency in python

I want to show PNG picture on canvas.
Before it I need to resize it and change transparency.
I found that I can load image and change alpha channel with PhotoImage like this:
image1 = PIL.Image.open('aqua.png')
image1.putalpha(128)
gif1 = ImageTk.PhotoImage(image1)
Also I can load PhotoImage and resize it like this:
gif1 = PhotoImage(file = 'aqua.png')
gif1 = gif1.subsample(5)
But I can't perform both this things on same PhotoImage
I understand that PhotoImage and ImageTk.PhotoImage are different classes in my code.
>> print (ImageTk.PhotoImage)
<class 'PIL.ImageTk.PhotoImage'>
>> print (PhotoImage)
<class 'tkinter.PhotoImage'>
I tried to found functionality that I need in both classes but without success.
Maybe I need perform subsample and than convert my tkinter.PhotoImage to PIL.ImageTk.PhotoImage and then perform putalpha but it sounds weird.
Please refer me to right direction about png cooking in Python.
Here is all my code:
from tkinter import *
import PIL
from PIL import Image, ImageTk
canvas = Canvas(width = 200, height = 200)
canvas.pack(expand = YES, fill = BOTH)
image1 = PIL.Image.open('aqua.png')
image1.putalpha(128)
gif1 = ImageTk.PhotoImage(image1)
# gif1 = PhotoImage(file = 'aqua.png')
# next line will not work in my case
gif1 = gif1.subsample(5)
canvas.create_image(0, 0, image = gif1, anchor = NW)
mainloop()
You can use the resize method included in the Image class. Here is the modified code:
from tkinter import *
from PIL import Image, ImageTk
canvas = Canvas(width = 200, height = 200)
canvas.pack(expand = YES, fill = BOTH)
image1 = Image.open('aqua.png')
image1.putalpha(128)
image1 = image1.resize((image1.width//5,image1.height//5))
gif1 = ImageTk.PhotoImage(image1)
canvas.create_image(0, 0, image = gif1, anchor = NW)
mainloop()

Opencv draw a rectangle in a picture were never shown

Hey everybody i have some trouble using opencv 3.x and python 3.x.
What i want to do is to draw a basic rectangle in a picture but the rectangle will never be drawn.
I read this similar thread but it doesn't helped me with my fault.
Python OpenCV: mouse callback for drawing rectangle
It would be nice if someone could give me a hint.
#!/usr/bin/env python3
import cv2
import numpy as np
Path = 'picture.jpg'
image_float_size = 400.0
image_int_size = int(image_float_size)
color = [0,255,0]
rectangle = False
def on_event(event,x,y,flags,param):
global startpointx,startpointy,rectangle
if event == cv2.EVENT_LBUTTONDOWN:
rectangle = True
startpointx = x
startpointy = y
print('Down',x,y) #debugging
cv2.rectangle(resized,(x,y),(x,y),(0,255,0),-1)
elif event == cv2.EVENT_LBUTTONUP:
rectangle = False
print('Up',x,y)
cv2.rectangle(resized,(startpointx,startpointy),(x,y),(0,255,0),-1)
elif event == cv2.EVENT_MOUSEMOVE:
if rectangle:
print('Move',startpointx,startpointy,x,y)#debugging
cv2.rectangle(resized,(startpointx,startpointy),(x,y),(0,255,0),-1)
# Read the image and convert it into gray
image = cv2.imread(Path)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# resize the image
ration = image_float_size / gray_image.shape[1]
dim = (image_int_size,int(gray_image.shape[0]*ration))
resized = cv2.resize(gray_image, dim, interpolation = cv2.INTER_AREA)
# set window for the image
cv2.namedWindow('window')
# mouse callback
cv2.setMouseCallback('window',on_event)
# wait forever for user to press any key, after key pressed close all windows
while True:
cv2.imshow('window',resized)
if cv2.waitKey(0):
break
cv2.destroyAllWindows()
You perform drawing (displaying of an image by using cv2.imshow) only once because cv2.waitKey(0) waits indefinitely. If you use some non-zero argument it will wait for that number of milliseconds. But notice that you're constantly rewriting/modifying an image. This is probably not what you want. I think you need to create a temporary (drawing) copy of an image first and restore it each time from original one before new drawing (rectangle).
#!/usr/bin/env python3
import cv2
import numpy as np
Path = 'data/lena.jpg'
image_float_size = 400.0
image_int_size = int(image_float_size)
color = [0,255,0]
rectangle = False
def on_event(event,x,y,flags,param):
global draw_image
global startpointx,startpointy,rectangle
if event == cv2.EVENT_LBUTTONDOWN:
rectangle = True
startpointx = x
startpointy = y
print('Down',x,y) #debugging
draw_image = resized.copy()
cv2.rectangle(draw_image,(x,y),(x,y),(0,255,0))
elif event == cv2.EVENT_LBUTTONUP:
rectangle = False
print('Up',x,y)
draw_image = resized.copy()
cv2.rectangle(draw_image,(startpointx,startpointy),(x,y),(0,255,0))
elif event == cv2.EVENT_MOUSEMOVE:
if rectangle:
print('Move',startpointx,startpointy,x,y)#debugging
draw_image = resized.copy()
cv2.rectangle(draw_image,(startpointx,startpointy),(x,y),(0,255,0))
# Read the image and convert it into gray
image = cv2.imread(Path)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# resize the image
ration = image_float_size / gray_image.shape[1]
dim = (image_int_size,int(gray_image.shape[0]*ration))
resized = cv2.resize(gray_image, dim, interpolation = cv2.INTER_AREA)
draw_image = resized.copy()
# set window for the image
cv2.namedWindow('window')
# mouse callback
cv2.setMouseCallback('window',on_event)
while True:
cv2.imshow('window', draw_image)
ch = 0xFF & cv2.waitKey(1)
if ch == 27:
break
cv2.destroyAllWindows()

Resources