Display opencv video with tkinter without recursion method - opencv

I have done real time face detection system, but I need to add gui for the program. Instead of using the solution from here. I does not want to read frame in a recursion way.
def show_frame():
_,frame = cap.read()
... #skip
lmain.after(10,show_frame)
It require a lot of refactoring in my previous code. So, I prefer read frame in a while loop way. But it does not work. Thanks for help.
import numpy as np
import cv2
import tkinter as tk
from PIL import Image, ImageTk
window = tk.Tk()
window.wm_title("Test")
imageFrame = tk.Frame(window, width=600, height=500)
imageFrame.grid(row=0, column=0, padx=10, pady=2)
#Capture video frames
lmain = tk.Label(imageFrame)
lmain.grid(row=0, column=0)
cap = cv2.VideoCapture(0)
def show_frame(frame):
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
# lmain.after(10, show_frame)
while True:
_,frame = cap.read()
show_frame(frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
window.mainloop()

Related

Stitching turtle & opencv video windows together

I have a program which opens turtle window & opencv video window together. I want to adjust 2 windows together or rather stitch them horizontally. How can I do this?
class PrettyWidget(QtGui.QWidget):
def __init__(self):
super(PrettyWidget, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(500, 100, 500, 500)
self.setWindowTitle('')
btn = QtGui.QPushButton('Please select video', self)
btn.resize(btn.sizeHint())
btn.clicked.connect(self.SingleBrowse)
btn.move(150, 200)
self.show()
def SingleBrowse(self):
video_path = QtGui.QFileDialog.getOpenFileName(self,'Single File',"./")
video = cv2.VideoCapture(video_path)
preprocess = preprocessing(config,"Occupancy Grid Matrix") # this makes turtle window having ogm
while(True):
ret,frame = video.read()
if frame is None:
break
cv2.imshow("",frame)
cv2.waitKey(1)
I want turtle window & opencv window to be displayed together in 1 window rather than adjusting 2 windows manually to be in center of screen.

ffmpeg lossless conversion from jpgs to video with huffyuv not working as expected

I'm trying to create a video from a set of jpg images. I would like that each frame of the video is exactly the same of the images used to create it. In order to get this result I'm using the following command:
ffmpeg -i %05d.jpg -c:v huffyuv test.avi
However if I check if the first frame is equal to the first image used to create the video I get some differences. In order to check this I used the following code:
import argparse
import cv2
import glob
import os
from os.path import isfile, join
parser = argparse.ArgumentParser()
parser.add_argument(
"video",
default = None,
help = 'video to be compared',
type = str)
parser.add_argument(
"image",
default = None,
help = 'image to be compared with the first frame of the video',
type = str)
args = parser.parse_args()
# opening video
cap = cv2.VideoCapture(args.video)
# reading first frame
ret, frame = cap.read()
# opening image
image = cv2.imread(args.image)
# computing difference between the first frame of the video and the image
diff = frame - image
# showing the differences: the two images are equal if the result is a black image
cv2.imshow("diff", diff)
cv2.waitKey(0)
cv2.destroyAllWindows()
If I use opencv to perform the conversion the result is as expected: no differences between the first frame and the first image used to create the video. This is python code used to generate the video from the images:
import argparse
import cv2
import glob
import os
parser = argparse.ArgumentParser()
parser.add_argument(
"jpg_folder",
default = None,
help = 'Path to folder with numbered jpg folder, must be alphabetically ordered (e.g 00000.jpg, 00001.jpg, ...)',
type = str)
parser.add_argument(
"avi_output",
default = None,
help = 'name of the outputavi file',
type = str)
parser.add_argument(
"--frame-rate",
default = 30,
help = 'number of frame per second used in the genrerated video (default is 30)',
type = int)
args = parser.parse_args()
#read images to be used to create the video
files = glob.glob(os.path.join(args.jpg_folder,'*.jpg'))
files.sort(key=lambda x: x)
#extract images dimensions
tmp_img = cv2.imread(files[0])
height, width, layers = tmp_img.shape
#create video writer with lossless codec
out = cv2.VideoWriter(args.avi_output,cv2.VideoWriter_fourcc('H', 'F', 'Y', 'U'), args.frame_rate, (width, height))
#read each image and add it to the video
for filename in files:
jpgImage = cv2.imread(filename)
out.write(jpgImage)
#release the resource used to write the video
out.release()
Am I missing some option in order to get the same result using ffmpeg?

Resize selected area of image

I want to increase / decrease the height of the image for the selected area only (The area between the white lines) as depicted in the image and not the outside of that area.
This is the same functionality which is performed in the app Manly - Body Muscle Editor Pro
How can I achieve that? Any help is appreciated.
I've never written code for IOS but I know OpenCV also works in IOS. Here I use the cv2.resize.
import cv2
import numpy as np
img = cv2.imread("1.jpg")
print(img.shape)
h = img.shape[0]
w = img.shape[1]
part_to_resize = img[120:240,:]
old_height = 120 #240-120
new_height = 200
final_result = np.zeros((h-(240-120)+new_height,w,3),dtype='uint8')
final_result[0:119,:] = img[0:119,:]
final_result[120:320,:] = cv2.resize(part_to_resize, (w, new_height))
final_result[321:h-old_height+new_height,:] = img[241:h,:]
cv2.imshow("final_result", final_result)
cv2.imshow("img", img)
cv2.waitKey()

error: (-215:Assertion failed) totalSampleCount > 0 in function 'GMM::endLearning'

Im trying to use the opencv to remove the background of my pictures.
When Im running a single file. It works out.
The code as below:
def bgremove(name,count):
import cv2
import numpy as np
# cv2.namedWindow('image',cv2.WINDOW_NORMAL)
#Load the Image
imgo = cv2.imread(name)# the place to input picture path
height,width = imgo.shape[:2]
#Create a mask holder
mask = np.zeros(imgo.shape[:2],np.uint8)
#Grab Cut the object
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
#Hard Coding the Rect… The object must lie within this rect.
rect = (10,10,width-30,height-30)
cv2.grabCut(imgo,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img1 = imgo*mask[:,:,np.newaxis]
#Get the background
background = imgo-img1
#Change all pixels in the background that are not black to white
background[np.where((background > [0,0,0]).all(axis = 2))] = [255,255,255]
#Add the background and the image
final = background + img1
DP1=count
#To be done – Smoothening the edges….
cv2.imwrite("A%s.JPG"%DP1, final)
However, when I use the function in a for loop. it pops-up:
error: (-215:Assertion failed) totalSampleCount > 0 in function
'GMM::endLearning'
when Im generating a group of pictures
I encountered this problem and the issue was that the rectangle rect was too small. I don't know the dimensions of your image but try a bigger rectangle and it may solve this.

how to display a full screen images with python2.7 and opencv2.4

I am trying to create a sort of image player with python and opencv. The images that i show are the same resolution on my screen and i would like to display them bordless in a full screen mode (without the windows bar at the bottom and the image bar at the top).
I accept also advice in order to improve my "var" used a counter for displaying the images:)
Thanks
def main():
var= 0
while True:
print 'loading images...'
if var==0:
img = cv2.imread('2-c.jpg')
var=var+1
else:
img = cv2.imread('2-d.jpg')
cv2.imshow("test",img)
key=cv2.waitKey(0)
if key==27:
break
EDIT:
I post an image and maybe i can explain myself better:
as you can see there is still the blue bar on top
Here is how I did it on my end:
cv2.namedWindow("window", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("window",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
cv2.imshow("window", img)
Thanks to Poko, I am gonna post the solution:
def main():
var= 0
while True:
print('loading images...')
if var==0:
img = cv2.imread('2-c.jpg')
var=var+1
else:
img = cv2.imread('2-d.jpg')
cv2.namedWindow("test", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("test", cv2.WND_PROP_FULLSCREEN, cv2.CV_WINDOW_FULLSCREEN)
cv2.imshow("test",img)
key=cv2.waitKey(0)
if key==27:
break
You have to create a window before doing your imshow.
take a look here: http://docs.opencv.org/modules/highgui/doc/user_interface.html#namedwindow
I had a case where the image on the Raspberry Pi was not displayed in full screen, but only at the top in a fixed size. It helped me to add another line to the above code.
import cv2
cap = cv2.VideoCapture(0)
width, height = cap.get(3), cap.get(4)
while True:
_, frame = cap.read()
cv2.namedWindow("window", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("window",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
cv2.moveWindow("window", int((Screen_Width/2)-(width/2)), int((Screen_Height/2)-(height/2)))
cv2.imshow("window", frame)
if cv2.waitKey(1) == 27: #Esc
cap.release()
cv2.destroyAllWindows()
break

Resources