1

I've been working on a project and have been kind of stumped after 6+ hours of googling and digging through openCV books.

import cv2
import numpy as np

cap = cv2.VideoCapture('tree.avi')
count = 0
x_pos = 0
y_pos = 0
a_x = 180
a_y = 180
frames = 60

if (cap.isOpened()== False): 
   print("Error opening video stream or file")

while(cap.isOpened()):
  ret, frame = cap.read()

  if ret == True:
    resized = frame
    scale_percent = 200
    width = int(frame.shape[1] * scale_percent / 100)
    height = int(frame.shape[0] * scale_percent / 100)
    dim = (width, height)

    if count < 50 or count >= 55:
      cv2.moveWindow('Frame', x_pos, y_pos)
      cv2.imshow('Frame', frame)

    if count in range(50, 55):
      resized = cv2.resize(frame, dim, interpolation = cv2.INTER_AREA)
      cv2.imshow('Frame',resized)
      x_pos = x_pos + int((a_x / frames) * (count - 50))
      y_pos = y_pos + int((a_y / frames) * (count - 50))

      cv2.moveWindow('Frame', x_pos, y_pos)

      count = count + 1

      if cv2.waitKey(25) & 0xFF == ord('q'):
        break

      else: 
        break

cap.release()

cv2.destroyAllWindows()

This is pretty generic code that I've taken as inspiration. What I want to achieve is to move the video window as it is playing to another location onscreen. I know from experience that simply adding another moveWindow() under the given one causes the window to fuzz between the two as it is applied to each frame.

Is there a way to perhaps make it so that, for example, frames 1~100 are at (100,100) and frames 101~200 are at (200, 200) and so on and so forth? Would be best if it's in real-time but any help regarding letting the user move the window while playing the video is very much appreciated.

Thanks in advance.

Update I found a way to manually set the video to move around for certain frames. However, this only seems to work for preset values. (ex) frames 50 ~ 55 Is there any way to use some external input in real-time?

J Hwang
  • 13
  • 4
  • Why you dont count the frames and when it hits the 101st frame then use `moveWindow` to (200,200) with an if statement? – Yunus Temurlenk Aug 28 '20 at 07:09
  • Sorry, didn't update the code accordingly. That part has been taken care of. What I want to achieve now is using any external output (maybe input the new position at each iteration or use a keystroke, etc) to do the same thing. – J Hwang Aug 28 '20 at 07:13
  • Opencv is not an interface based library. You can achieve it by using simple keywords or some simple click events as you achieved before – Yunus Temurlenk Aug 28 '20 at 07:15
  • Oh... I think I see now. I'm thinking of inputting some arbitrary data concerning the number of increments to move at each frame into a txt file and reading each corresponding line for each frame. The part of the project that provides that data is already finished so maybe this will work. – J Hwang Aug 28 '20 at 07:20

1 Answers1

0

What I want to achieve is to move the video window as it is playing to another location onscreen

If the above statement is your main concern, then use FileVideoStream.

As I have mentioned in my previous answer:

VideoCapture pipeline spends the most time on the reading and decoding the next frame. While the next frame is being read, decode, and returned the OpenCV application is completely blocked.

This means while you are moving the video, the application is blocked since the pipeline can't decode the next frame.

For instance: Below is displaying frames, while dragging the window manually.

import cv2
import time
from imutils.video import FileVideoStream

vs = FileVideoStream('result.mp4').start()
time.sleep(0.2)

while True:
    frame = vs.read()

    cv2.imshow("out", frame)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

vs.stop()
cv2.destroyAllWindows()

Now if we merge the code with some of your variables:

import cv2
import time
from imutils.video import FileVideoStream

vs = FileVideoStream('result.mp4').start()
time.sleep(0.2)

count = 0
x_pos = 0
y_pos = 0
a_x = 180
a_y = 180
frames = 60


while True:
    frame = vs.read()

    scale_percent = 200
    width = int(frame.shape[1] * scale_percent / 100)
    height = int(frame.shape[0] * scale_percent / 100)
    dim = (width, height)

    if count in range(0, 55):
        resized = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
        cv2.imshow('Frame', resized)
        x_pos = x_pos + int((a_x / frames) * (count - 50))
        y_pos = y_pos + int((a_y / frames) * (count - 50))

        cv2.moveWindow('Frame', x_pos, y_pos)

    cv2.imshow("out", frame)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

vs.stop()
cv2.destroyAllWindows()

You will see two windows, one is displaying, the second window is moving from the right location to the left location of the window.

enter image description here

Ahmet
  • 7,527
  • 3
  • 23
  • 47