why the webcam is showing anything in opencv - python

I am making a gui with a button to make webcam on and off. and it is working but when i open it again after closing it then its shows only black screen.
how to resolve this issue.
Here is my code. my whole code is huge so i posted on the webcam part here.
i updated my code .......................
import tkinter as tk
from tkinter import *
import cv2
import numpy as np
from PIL import Image, ImageTk, ImageGrab
cap = cv2.VideoCapture(0)
webcam = None
WEBCAM_SIZE = (280, 200)
def read_frame(imgbox):
if cap.isOpened():
ret, frame = cap.read()
if ret:
frame = cv2.flip(frame, 1)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = cv2.resize(frame, WEBCAM_SIZE)
image = Image.fromarray(frame)
imgbox.image.paste(image)
webcam.after(20, read_frame, imgbox)
def stop_webcam(event):
global webcam
if webcam:
webcam.destroy()
webcam = None
cap.release()
def start_webcam():
global webcam
cap.open()
if webcam is None:
cap.isOpened()
webcam = tk.Toplevel()
#webcam = tk.lift()
webcam.attributes("-topmost", True) #it keep the window on top of others
webcam.geometry('{}x{}+5+520'.format(WEBCAM_SIZE[0], WEBCAM_SIZE[1]))
webcam.overrideredirect(1)
imgbox = tk.Label(webcam)
imgbox.pack()
imgbox.image = ImageTk.PhotoImage(image=Image.new('RGB',WEBCAM_SIZE,(0,0,0)))
imgbox.config(image=imgbox.image)
#webcam.bind('', stop_webcam)
read_frame(imgbox)
cap_btn = ttk.Button(frame, image=web, width=20, command=change_w)
cap_btn.grid(row=0, column=2)
cap_btn.image = web
def change_w():
if cap_btn.image == web:
start_webcam()
cap_btn.config(image=web2)
cap_btn.image = web2
else:
stop_webcam(None)
cap_btn.config(image=web)
cap_btn.image = web
web = PhotoImage(file='webcam.png')
web2 = PhotoImage(file='bl.png')
root.mainloop()

Related

The video I recorded via webcam with opencv does not open

i tried to make a webcam video recording to a file using openCV python, i could not open the file with any of my video players. here is the code,
it works fine but I stop the recording and looking the file and it doesn't open. I guess there are some codec issues. I tried also (*'XVID') .avi format. but changed nothing.
here is the code
please help
from tkinter import *
from PIL import ImageTk, Image
import cv2
import threading
root = Tk()
root.geometry("750x500")
root.configure(bg="#0059aa")
#camera
camera_frame = LabelFrame(root, text=u"KAMERA STREAMING",
border=2,
width=398,
height=265)
camera_frame.place(x=183,y=33)
camera_label = Label(camera_frame,width=55,height=14)
camera_label.grid(row=0,column=0)
global capture
capture = cv2.VideoCapture(0)
# edit: close following two lines
# capture.set(3,250)
# capture.set(4,225)
global out
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('blabla.mp4', fourcc, 20.0, (640, 480))
global stopCam
stopCam = False
def show_frames():
global capture
# read the capture
ret, frame = capture.read()
# turned into image and display
cv2image = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
height, width, channels = cv2image.shape
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image = img)
camera_label.imgtk = imgtk
camera_label.configure(image=imgtk,width=width,height=height)
# record
global out
out.write(frame)
# quit
if (stopCam):
out.release()
capture.release()
cv2.destroyAllWindows()
return
camera_label.after(20,show_frames)
p1 = threading.Thread(target=show_frames)
buttonLabel = Label(camera_frame)
buttonLabel.grid(row=1,column=0)
connectButton = Button (buttonLabel, text=u"connect", command=p1.start, width=14)
connectButton.grid(row=0,column=0)
stopButton = Button(buttonLabel, text=u"stop", command= lambda: globals().update(stopCam=True) , width=14)
stopButton.grid(row=0,column=1)
root.mainloop()
edit (also solved way):
I looked at some code that worked properly. and I saw capture.set() as the difference. When I close the capture.set() lines, I had no problems with either streaming or recording. Now the main problem is that I have to show the video in a label with a certain size. Without set() the video size gets too big. how can i solve it now?

How to display an image from OpenCV in a Tkinter interface?

I am trying to continuously display and replace an image in a Tkinter interface taken from OpenCV's VideoCapture. However, I am getting the following error that I think is a result of improper formatting of the image numpy array:
TypeError: unhashable type: 'numpy.ndarray'
How can I reformat it to all it to display properly? Below is my code:
import tkinter as tk
import cv2
import numpy as np
from PIL import ImageTk, Image
main = tk.Tk()
main.title("Hole Pattern Recognition")
main.geometry("300x300")
frame = tk.Frame(main)
frame.pack()
def startScan():
global main, frame
#begins utilizing webcam for scan
cap = cv2.VideoCapture(0)
while(True):
ret,img = cap.read()
img = ImageTk.PhotoImage(img)
panel = tk.Label(main, image = img)
panel.pack(side = "bottom", fill = "both", expand = "yes")
ch = cv2.waitKey(1)
if ch == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
startButton = tk.Button(frame,
text="Start Scan",
fg="blue",
command=startScan)
startButton.pack(side=tk.TOP)
main.mainloop()
First you need to use PIL.Image.fromarray() to convert the captured image to format supported by tkinter.
Second better not use while loop in main thread as it will block the tkinter mainloop. Use after() instead.
import tkinter as tk
from PIL import Image, ImageTk
import cv2
cap = None
main = tk.Tk()
main.title('Hole Pattern Recognition')
#main.geometry('300x300')
frame = tk.Frame(main)
frame.pack()
def startScan():
global cap
def scan():
ret, img = cap.read()
if ret:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
tkimg = ImageTk.PhotoImage(img)
panel.config(image=tkimg)
panel.tkimg = tkimg # save a reference to the image to avoid garbage collection
panel.after(25, scan) # change 25 to other value to adjust FPS
if cap is None:
cap = cv2.VideoCapture(0)
scan() # start the capture loop
else:
print('capture already started')
startButton = tk.Button(frame, text='Start Scan', fg='blue', command=startScan)
startButton.pack()
panel = tk.Label(main)
panel.pack()
main.mainloop()
if cap:
cap.release()

Opencv and Tkinter: How can i automatically show webcam video?

I am having a problem where i cant find a way to display Opencv webcam video in a Tkinter frame, I would've used the basic code online but the problem is that i cant seem to make it automatically make a frame when the webcam is connected.
I've tried modifying the code i found online, But at this point i honestly don't have any idea of what i am doing.
import cv2
from tkinter import *
import PIL
from PIL import Image, ImageTk
root = Tk()
root.bind('<Escape>', lambda e: root.quit())
lmain = Label(root)
lmain.pack()
print("[INFO] Making variables")
ImageSource = 0
window_name = "AutoCam"
cap = cv2.VideoCapture(ImageSource)
print("[INFO] Made variables ")
def CheckSource():
print("[INFO] Checking image source")
while True:
print("[INFO] Reading frame")
cap = cv2.VideoCapture(ImageSource)
while cap.isOpened():
_, frame = cap.read()
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = PIL.Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, show_frame)
print("[INFO] cv2.imshw done")
if cv2.waitKey(1) & 0xFF == ord('q'):
cv2.destroyAllWindows()
cv2.waitKey(0)
break
Check_root = False
def CheckRootDef():
if Check_root:
CheckSource()
CheckRootDef()
root.mainloop()
check_root = True
CheckRootDef()
i expect it to make a costum Tkinter window and show my webcam footage live on it, And that as soon as the webcam is detected.

How to add a CV2 tracking bar in a tkinter window

How to add a cv2 trackbar to a Tkinter window?
I have 2 snippets of code that my teammates have made, but it is difficult to integrate them in the same window.
I am able to use them in separate windows but I want to use them in the same window.
CODE FOR THE VIDEO PLAYING IN TKINTER:
import cv2
import tkinter as tk
from tkinter import *
# from tkinter import ttk
# from ttk import Frame
# import ImageTk
white = "#ffffff"
lightBlue2 = "#adc5ed"
font = "Constantia"
fontButtons = (font, 12)
maxWidth = 800
maxHeight = 480
#Graphics window
mainWindow = tk.Tk()
mainWindow.configure(bg=lightBlue2)
mainWindow.geometry('%dx%d+%d+%d' % (maxWidth,maxHeight,0,0))
mainWindow.resizable(0,0)
# mainWindow.overrideredirect(1)
mainFrame = Frame(mainWindow)
mainFrame.place(x=20, y=20)
#Capture video frames
lmain = tk.Label(mainFrame)
lmain.grid(row=0, column=0)
cap = cv2.VideoCapture('test.mp4')
def show_frame():
ret, frame = cap.read()
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image).resize((760, 400))
imgtk = ImageTk.PhotoImage(image = img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, show_frame)
closeButton = Button(mainWindow, text = "CLOSE", font = fontButtons, bg = white, width = 20, height= 1)
closeButton.configure(command= lambda: mainWindow.destroy())
closeButton.place(x=270,y=430)
show_frame() #Display
mainWindow.mainloop() #Starts GUI
And I have a second snippet of code that uses cv2 to display the track bar and changes the position of the video.
import cv2
CURRENT_FRAME_FLAG = cv2.CAP_PROP_POS_FRAMES
TOTAL_FRAMES_FLAG = cv2.CAP_PROP_FRAME_COUNT
WIN_NAME = "Frame Grabber"
POS_TRACKBAR = "pos_trackbar"
cap = cv2.VideoCapture('C:/Users/ayush/Desktop/test.mp4')
ret, frame = cap.read()
def dummy():
pass
def save_image():
filename = "image_%0.5f.png" % t.time()
cv2.imwrite(filename, frame)
def seek_callback(x):
global frame
i = cv2.getTrackbarPos(POS_TRACKBAR, WIN_NAME)
cap.set(CURRENT_FRAME_FLAG, i-1)
_, frame = cap.read()
cv2.imshow(WIN_NAME, frame)
def mouse_callback(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDBLCLK:
save_image()
def skip_frame_generator(df):
def skip_frame():
global frame
cf = cap.get(CURRENT_FRAME_FLAG) - 1
cap.set(CURRENT_FRAME_FLAG, cf+df)
cv2.setTrackbarPos(POS_TRACKBAR, WIN_NAME, int(cap.get(CURRENT_FRAME_FLAG)))
_, frame = cap.read()
return skip_frame
cv2.namedWindow(WIN_NAME)
cv2.createTrackbar(POS_TRACKBAR, WIN_NAME, 0, int(cap.get(TOTAL_FRAMES_FLAG)), seek_callback)
cv2.setMouseCallback(WIN_NAME, mouse_callback)
actions = dict()
actions[ord("D")] = skip_frame_generator(10)
actions[ord("d")] = skip_frame_generator(1)
actions[ord("a")] = skip_frame_generator(-1)
actions[ord("A")] = skip_frame_generator(-10)
actions[ord("q")] = lambda: exit(0)
actions[ord("s")] = save_image
while True:
cv2.imshow(WIN_NAME, frame)
key = cv2.waitKey(0) & 0xFF
actions.get(key, dummy)()
I have to integrate the cv2 trackbar into the Tkinter window.
I am able to integrate but as I don't know how to use implement CV2 trackbar in tkinter, I am not able to do anything.
Please Help.
Try using tkinter Scale widgets instead of cv2 trackbars. They are slightly different but they should be fairly easy to swap out and work about the same. Then you can easily add them in your tkinter window/frame.

stream from thermal camera (ip camera) on python , connection error

i want to stream from a thermal camera, usually it export its frames as gray scale frames
the thermal camera is an IP camera , i tried different codes and package but with no output.
when i change the code a little bit to view from a USB camera it works normally, so any help please.
this is the code i have tried :
import sys
sys.path.append('C:\Python27\Lib\site-packages')
import Tkinter as tk
import cv2
from PIL import Image, ImageTk
i=0
window = tk.Tk()
window.title('thermal image')
var = tk.IntVar()
width, height = 800, 600
cap = cv2.VideoCapture(0)
cap.open("http://169.254.110.119/")
left_label = tk.Label(window)
left_label.pack(side="left")
right_label = tk.Label(window)
right_label.pack(side="right")
def show_frame():
_, frame = cap.read()
print frame
if frame != None:
frame = cv2.flip(frame, 1)
img = Image.fromarray(frame)
imgtk = ImageTk.PhotoImage(image=img)
left_label.imgtk = imgtk
left_label.configure(image=imgtk)
left_label.after(10, show_frame)
show_frame()
window.mainloop()
I think that the image from the websitre is not being grabbed in the code, what worked for me was
img_requested = requests.get(url)
img_arr = np.array(bytearray(img_requested.content), dtype=np.uint8)
frame = cv2.imdecode(img_arr, -1)
And there you would get the frame (color picures/video).Keep in mind that you need to import requests and numpy as np.
It is important if you are using IP Webcam that you do not forget to write the '/shot.jpg'
at the end of the url, like this: 'http://190.160.0.0:8080/shot.jpg', so that it effectivelly grabs the image.

Categories

Resources