I am running into strange problems with the Python wrapper for OpenCV. I am using the cv2 binding and have been able to do a lot with it but the latest problem is my inability to create a VideoWriter.
When I try to create a video writer using this command:
cv2.VideoWriter('foo.out.mov', cv2.cv.CV_FOURCC('m','p','4','v'), 25, (704, 480), 1)
I get the following error:
error: /builddir/build/BUILD/OpenCV-2.3.1/modules/highgui/src/cap_gstreamer.cpp:483: error: (-210) Gstreamer Opencv backend doesn't support this codec acutally. in function CvVideoWriter_GStreamer::open
When create a VideoCapture I can successfully retrieve frames by using the read method, but any calls to the get method to retrieve parameters such as frame width, frame height, or FOURCC code all return 0.0.
I wanted to get the exact codec from the file I am opening to pass this into VideoWriter, but since this only returns 0.0 I don't know what to do.
Any help would be greatly appreciated.
Try passing -1 as the fourcc parameter. This should pop up a dialog and let you choose a video codec. I use it this way, and works great.
cv2.VideoWriter('foo.out.mov', -1, 25, (704, 480), 1)
Related
im trying to implement the GSOC background subtractor from openCV.
fgbg = cv.bgsegm_BackgroundSubtractorGSOC()
fgmask = fgbg.apply(frame)
but this gives me following error:
fgmask = fgbg.apply(frame)
TypeError: Incorrect type of self (must be 'bgsegm_BackgroundSubtractorGSOC' or its derivative)
and
fgmask = cv.bgsegm_BackgroundSubtractorGSOC.apply(frame)
gives me this error:
fgmask = cv.bgsegm_BackgroundSubtractorGSOC.apply(frame)
TypeError: descriptor 'apply' requires a 'cv2.bgsegm_BackgroundSubtractorGSOC' object but received a 'numpy.ndarray'
The documentation for .apply() says i only need to supply an inputarray (the frame), the output location and the learning rate. Changing .apply(frame) to .apply(frame, output, -1) does not fix the error
how do i correctly implement a bgsegm_BackgroundSubtractorGSOC object and use it on my image?
i read this post but it seems i am failing a step before that already
GSOC and the other background subtraction methods (other than MOG2 and KNN) are located in the extra modules and require the opencv-contrib library to be installed.
Once it is installed, the module can be used by writing:
backSub = cv.bgsegm.createBackgroundSubtractorGSOC()
I have been trying to create a CanvasImage item in python using goocanvas however when I try to use the CanvasImage function it gives me an error.
pb = GdkPixbuf.Pixbuf.new_from_file_at_scale("image2.jpg", 1920, 1080, True)
image = GooCanvas.CanvasImage(pb, 200, 200)
TypeError: GObject.init() takes exactly 0 arguments (3 given)
Am I missing something or am I using a wrong function to create an image on the canvas.
I am referring to this as there is no proper documentation for goocanvas bindings in python: https://developer.gnome.org/goocanvas/stable/GooCanvasImage.html
If Goocanvas is not suitable for python, please suggest a different canvas that I could integrate and use in python.
Thank You
Perhaps it's the call.
This is from the goocanvas github : https://github.com/GNOME/goocanvas/blob/33694b33cc337be86d8c848825a463e52bb1a2c0/bindings/python/demo.py#L190
Also the project's github states that it is no longer supported.
An actively developed and better documented library is PyGObject.
https://pygobject.readthedocs.io/en/latest/index.html
To display images: https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/Image.html#Gtk.Image
I am currently try to adjust the resolution of the video by opencv, according to my research, cap.set is the method to do so. thus, I write the code below:
cap = cv2.VideoCapture('IMG_2957.MOV')
for i in range(19):
print (""+str(i)+" "+str(cap.get(i)))
cap.set(3,160) #Width
cap.set(4,120) #Height
for i in range(19):
print (""+str(i)+" "+str(cap.get(i)))
very surprise, the value of "CV_CAP_PROP_FRAME_WIDTH" and "CV_CAP_PROP_FRAME_HEIGHT" remain unchanged
Before the cv.set
3 1920.0
4 1080.0
And after the setting, the frame was not set as what I want
After the cv.set
3 1920.0
4 1080.0
Is that we are not able to change the resolution by setting its property? Can anyone advice me the usage of .set of cv2.videocapture?
More information about the version:
Python 3.6.0 [MSC v.1900 64 bit (AMD64)] on win32
>>> import cv2
>>> cv2.__version__
'3.4.0'
First, it is important to understand that VideoCapture is more than just a class to playback a video file. It can also connect to a stream or a camera for example. Then it may have properties that will work only for specific cases and that is why they have a set / get generic function. With a webcam, if your webcam/drivers allow it you may set the resolution for example with the code snippet you supply.
The set function returns a bool value in C++ (and in python) not sure if this means that it is set or not, but you can check it out, probably yours returns false. I am not sure, since I had not checked that and the documentation does not provide an explanation.
In a video, it will read each frame, but it may not change the properties of the video. What can you do then? Depends on what you are planning to do with it.
You may use the resize, for example:
retval, frame = cap.read()
res = cv2.resize(frame,(160, 120), interpolation = cv2.INTER_CUBIC)
Then you may save the video with VideoWritter or do any image manipulation to it.
from VideoCapture import Device
cam = Device()
cam.setResolution(320, 240)
cam.saveSnapshot('demo.jpg')
I use VideoCapture in Windows Python2.7 .I do not know what`s wrong.How do I solve this problem.
Traceback (most recent call last):
File "D:/ideaProject/python_workspace/webcap/webcap/test/vc.py", line 8, in <module>
cam.setResolution(320, 240)
File "D:\SoftWare\Python27\lib\VideoCapture.py", line 90, in setResolution
self.dev.setresolution(width, height)
vidcap.Error: Cannot set capture resolution.
After I read the VideoCapture.py with a deep look,I find a solution :
from VideoCapture import Device
cam = Device()
cam.getImage(timestamp=0).resize((320, 240)).save('demo.jpg', quality=80)
I can get the right size of the photo.Perhaps I use wrong method.
I have a question, your solution looks more like a workaround. I guess you didn't change your camera's resolution, what your code did is to use your camera to capture an original picture and by using resize() function to change the captured picture's size then. That means, what you are doing looks like you capture a picture first(which doesn't have your desired resolution), then you go to edit that captured picture. If I'm wrong, I appreciate you can point that out cause I'm faced with this problem, too.
i'm working with camera, with pygame, i wrote this code:
import pygame.camera
import pygame.image
pygame.camera.init()
list_webCam = pygame.camera.list_cameras()
webcam = pygame.camera.Camera(list_webCam[0],(640,480))
webcam.start()
img = webcam.get_image()
pygame.image.save(img, "photo.jpg")
pygame.camera.quit()
but it returns me this error:
Traceback (most recent call last):
File "C:\Users\Fulvio\Desktop\pygame.Camera.py", line 11, in <module>
pygame.image.save(img, "photo.jpg")
TypeError: must be pygame.Surface, not None
Fors ome reason, you didn't get the expected image. This error means the "img" object is "None" - that is, your call to get_image didn't get the expected result.
As far as I can tell, you are making all the needed calls to get the camera roling, and grabbing an image - so, you'd better do some debugging in there, and check introspect what your webcam object is, and try to call the .get_image() method interactively, observing what it returns.
To do that, you may either paste the relevant lines directly in a Python console, or
put the `import pdb; pdb.set_trace()" statements at the beginning, and proceed through using the Python Debugger. (For such a short snippet, you'd probably be better pasting/typing directly in the interpreter).
If everything is fine in your setup, it may be that the camera may need some "warm-up" time between the start and get_image calls. If using the interactive mode you get your image, try adding an arbitrary delay (say 200ms), after the start call (use pygame.time.delay for that)
Also, as far as I know, pygame can't encode images to "jpg" - you have to save then as "bmp" - or use some other library to handle the pygame.Surface object and save to other image formats.
I just passed from python 3.5 to 2.7 and I was having the same problem you have.
After a quick search I solved it:
get_image want 1 parameter: the pygame suface!
So, you can do this:
import pygame
import pygame.camera
from pygame.locals import *
pygame.camera.init()
cam = pygame.camera.Camera(0,(640,480),"RGB")
cam.start()
img = pygame.Surface((640,480))
cam.get_image(img)
pygame.image.save(img, "img.jpg")
cam.stop()
img = pygame.Surface((640,480))
cam.get_image(img)
I guess you don't need this anymore since it's passed more than 1 year but I hope it can help someone else.