Thread is not opening the target function in python - python

I want to open a function which shows the Loading VIDEO on the screen by cv2.imshow() method called.
First I want to demostrat the code and then the problem.
import cv2
import threading
def Load():
video = cv2.VideoCapture('Loading.mov')
if video.isOpened() == True:
cv2.namedWindow("The Video")
cv2.moveWindow("The Video", 500,200)
elif video.isOpened() == False:
print('No Data For Loading Video')
return 0
while video.isOpened():
_, frame = video.read()
if _ == True:
cv2.imshow("The Video",frame)
if cv2.waitKey(10) & 0xff == 27:
break
if _ == False :
break
cv2.destroyAllWindows()
video.release()
t = threading.Thread(target = Load)
t.start()
Now, Problem :
When I call the t.start() FOR THE FIRST TIME the thread gets started and shows the video properly.
After the loop breaks, if I try again to make a new t as a thread and .start() it again, it doesn't show anything at all ! Not errors, nothing !
I am using spyder to re run the codes.
And I want to re run the video whenever I needed .
Now, Where is the problem ?

I tried your code with an mp4-Video (http://techslides.com/demos/sample-videos/small.mp4) and it works. I converted said video to mov with https://video.online-convert.com/convert-to-mov and it still works...
Although I may have an educated guess:
you should try to do every call with a fresh instance of cv2.
I assume the problem could be, that the second call of the thread inherits the state of the first call (especially the internal state of cv2), since it's only a function an therefor the video is in state "already played" or something and doesn't show anything more.
so if you put everything in a class and call with a new instance of cv2 everytime Load() is called, it might work.
import cv2
import threading
class Video:
def play(self):
video = cv2.VideoCapture('small.mov')
if video.isOpened() == True:
cv2.namedWindow("The Video")
cv2.moveWindow("The Video", 500,200)
elif video.isOpened() == False:
print('No Data For Loading Video')
return 0
while video.isOpened():
_, frame = video.read()
if _ == True:
cv2.imshow("The Video",frame)
if cv2.waitKey(10) & 0xff == 27:
break
if _ == False :
break
cv2.destroyAllWindows()
video.release()
def Load():
v=Video()
v.play()
del v
t = threading.Thread(target = Load)
t.start()

Related

Async process not switching a boolean trigger

I have the following steps I need to follow:
1 - I need to start a camera instance on OpenCV
2 - I need to send the camera's data to some outside source every 2 seconds, but the video feed obviously cannot stop in the meantime
So I made two main async functions: "flip_trigger", which switches a boolean variable every 2 seconds, and "camera_feed", which also consumes the same "send_image" trigger that s switched by "flip_trigger". The two must run at the same time.
send_image = False
async def flip_trigger():
global send_image
while True:
await asyncio.sleep(2)
send_image = not send_image
print("Awaiting image")
async def camera_feed():
global send_image
face_names = []
face_usernames = []
video_capture = cv2.VideoCapture(0)
while True:
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if(send_image):
ret, frame = video_capture.read()
#(...) some other code
else:
ret, frame = video_capture.read()
cv2.imshow('Video', frame)
continue
#(...) some other code
ret, frame = video_capture.read()
cv2.imshow('Video', frame)
video_capture.release()
cv2.destroyAllWindows()
break
async def start_camera():
task1 = asyncio.create_task(flip_trigger())
task2 = asyncio.create_task(camera_feed())
await asyncio.wait({task1, task2}, return_when=asyncio.FIRST_COMPLETED)
asyncio.run(start_camera())
The problem is: while debugging the code on VSCode, it seemingly never gets past the "await asyncio.sleep(2)" line, and if I remove the "await" parameter, the code seems to get stuck inside the "flip_trigger" function.
How do I make these functions work at the same time, and make "camera_feed" capture the "send_image" boolean switches in real time?
When you call await asyncio tries to continue other tasks in the loop.
Imagine when await especially in combination with asyncio.sleep is called it pauses the execution and it hops to another await section region where it can continue.
There normal python code is executed sequentially until the next await is reached.
Your camera_feed has no await, that means it will continuously loop forever/until the break.
It won't go back to flip_trigger.
You can use asyncio.sleep(0) to enable a ping pong between both functions.

Why is cv2 showing a blank grey square?

I have a python program using the cv2 library, that chooses a random US state, pulls the image of the state from a folder and displays it. It was working fine, so I saved it, and suddenly, instead of showing the image, it shows a blank grey square and crashes. Why is it doing this, and how can I fix it? Heres the sample images:
and heres the code:
import cv2
import random
import time
#makes a list of the states
def states():
states = ['alabama','alaska','arizona','arkansas','california',
'colorado','connecticut','deleware','florida','georgia','hawaii',
'idaho','illinois','indiana','iowa','kansas','kentucky','louisiana',
'maine','maryland','massachussets','michigan','minnesota',
'mississipi','missouri','montana','nebraska','nevada',
'new_hampshire','new_jersey','new_mexico','new_york',
'north_carolina','north_dakota','ohio','oklahoma','oregon',
'pennsylvania','rhode_island','south_carolina','south_dakota',
'tennessee','texas','utah','vermont','virginia','washington',
'west_virginia','wisconsin','wyoming']
while True:
#choose a random state from the states list
state = random.choice(states)
#take a picture from the states folder, and display it
img = cv2.imread('picture_files/states/' + state + '.png')
cv2.imshow('guess the state!', img)
#checks if you typed the right state,
#and gives an appropriate response
guess = input("guess the state! (type stop to stop!)\n")
if guess.lower() == state:
print("Correct!")
time.sleep(2)
print("Lets do it again!")
elif guess.lower() == "stop":
break
else:
print("Nope! It was " + state + ". Keep trying!")
time.sleep(2)
if __name__ == '__main__':
states()
Basically you are missing some cv2.waitKey() function to show the image (see also here).
This is a possible example for a solution.
def pick_a_state():
states = ['a','b'] # replace with your list
return random.choice(states)
def show_state(state):
img = cv2.imread(state + '.png', cv2.IMREAD_UNCHANGED)
cv2.imshow('guess the state!', img)
cv2.waitKey(1000)
def get_the_answer(state):
guess = raw_input("guess the state! (type stop to stop!)\n")
if guess.lower() == state:
print(state)
print("Correct!")
time.sleep(2)
print("Lets do it again!")
return 1
elif guess.lower() == "stop":
return 0
else:
print("Nope! It was " + state + ". Keep trying!")
time.sleep(2)
return 1
if __name__ == '__main__':
while True:
state = pick_a_state()
show_state(state)
if get_the_answer(state) == 0:
cv2.destroyAllWindows()
break
Please analyze the code to understand how it works. Hope can help.
I've had an error like this before where opencv would not open and have been successful in a few ways to solve it.
Add cv2.waitKey(0) at the end of your function and then add
cv2.destroyAllWindows() underneath your calling of states()
like this:
if __name__ == '__main__':
states()
cv2.destroyAllWindows()
Install opencv-contrib-python.
Try installing it with the command pip3 install opencv-contrib-python==4.4.0.46.

How to capture an image by keyboard input using opencv?

I wanted to capture an image directly from my camera by keyboard input. For example, when I press 'r', the camera takes a picture of what it sees. Here's my code:
import cv2 as cv
import time
cap = cv.VideoCapture(0)
while True:
_, img = cap.read()
cv.imshow('original', img)
if cv.waitKey(1) == ord('q'):
break
elif cv.waitKey(1) == ord('r'):
cv.imwrite('data_{}.jpg'.format(time.time()), img)
print('saving an image')
continue
else:
continue
cap.release()
cv.destroyAllWindows()
This code is actually working but not that good. Sometimes, when I press 'r' it not saving any image into my directory. How could I improve this code so whenever I press 'r' it's certainly saving an image?
You're supposed to capture a key and then check its value.
while True:
key = cv.waitKey(1)
if key == ord('q'):
break
elif key == ord('r'):
# do your stuff here
pass
The way you've done it transverses the conditional blocks with a new key press at a time. Let's say you first press 'r'. The loop is currently at if cv.waitKey(1) == ord('q'), which evaluates false, so it continues to the next check. By this time you're not pressing anything, so cv.waitKey(1) will return -1 and your check for 'r' will be false. And on and on you go.

Python ImageGrab Not Working With Input

In my program, I'm taking a screenshot of a part of my screen, which works. But when I add anything in front of calling the function it's in, it no longer gets past the ImageGrab part.
This works:
def takePictures():
print("3")
if __name__ == '__main__':
print("1")
im = ImageGrab.grab(bbox=(760, 250, 1160, 680)) # X1,Y1,X2,Y2
print("2")
im.save('ALL.png')
#im.show()
takePictures()
This doesn't:
def takePictures():
print("3")
if __name__ == '__main__':
print("1")
im = ImageGrab.grab(bbox=(760, 250, 1160, 680)) # X1,Y1,X2,Y2
#^^^ Doesnt get past this line
print("2")
im.save('ALL.png')
#im.show()
if input() == "":
takePictures()
I've also tried it with inputs from keys on a different window and it's the same.
Your program will pause at
if input() == "":
takePictures()
until you activate the python executing window and hit the enter key.
If you want to take screen shots, you can use, say
time.sleep(10)
giving yourself 10 seconds to activate the window you want to take a screen shot of.

How to stop and start kinect in openkinect?

I am using the openkinect with python bindings and running the following demo app...
#!/usr/bin/env python
import freenect
import cv
import frame_convert
cv.NamedWindow('Depth')
cv.NamedWindow('Video')
print('Press ESC in window to stop')
def get_depth():
return frame_convert.pretty_depth_cv(freenect.sync_get_depth()[0])
def get_video():
return frame_convert.video_cv(freenect.sync_get_video()[0])
while 1:
cv.ShowImage('Depth', get_depth())
cv.ShowImage('Video', get_video())
if cv.WaitKey(10) == 27:
break
When I press escape this program does not stop. So I have tried to execute it as follows
#!/usr/bin/env python
import freenect
import cv
import frame_convert
cv.NamedWindow('Depth')
cv.NamedWindow('Video')
print('Press ESC in window to stop')
def get_depth():
return frame_convert.pretty_depth_cv(freenect.sync_get_depth()[0])
def get_video():
return frame_convert.video_cv(freenect.sync_get_video()[0])
for i in range(10):
cv.ShowImage('Depth', get_depth())
cv.ShowImage('Video', get_video())
if cv.WaitKey(10) == 27:
break
to execute it 10 times only.
The problem is that the program never stops and keep displaying the images. I think that one needs to stop kinect.
I want to take the depth image at a specific time instance. So it means that the kinect has to be restarted. I cant keep it executing all the time.
Could anybody help me in this please.
No need to stop the Kinect: it seems the condition to break the while is never met.
This may depend on the platform, the opencv version and several other factors.
Try something like:
while 1:
cv.ShowImage('Depth', get_depth())
cv.ShowImage('Video', get_video())
k = cv.WaitKey(10) # k contains integer keycode
if chr(k) == 'q': # press q to exit
break
To double check why pressing the ESC key does not pass the keycode 27 to cv.WaitKey try printing the keycode k above and see what happens when you hit ESC.
use int value of 'q' instead of 'q'
k=0
while k != 1048689: # key value of 'q' is 1048689
cv.ShowImage('Depth', get_depth())
cv.ShowImage('Video', get_video())
k = cv.WaitKey(10) # k contains integer keycode

Categories

Resources