Reputation: 65
I do not want to use OpenCV, Pygame or ImageIO because all three are HUGE, and I want to compile my program into a binary, using any of these libraries is causing the output to be 100MB or more when I am only using one functionality of those libraries.
I know that it is possible to capture a photo using c/++ but I do not know a single thing about low-level programming languages. So I was hoping for help.
NOTE: If anyone knows how to do this in C/++ but not ctypes, no problem, just post it here and I can modify it into python ctypes syntax.
Upvotes: 1
Views: 108
Reputation: 12160
I've published a lightweight Python camera library on PyPI: https://pypi.org/project/lite-camera/
To use it:
import litecam
camera = litecam.PyCamera()
if camera.open(0):
window = litecam.PyWindow(
camera.getWidth(), camera.getHeight(), "Camera Stream")
while window.waitKey('q'):
frame = camera.captureFrame()
if frame is not None:
width = frame[0]
height = frame[1]
size = frame[2]
data = frame[3]
window.showFrame(width, height, data)
camera.release()
Upvotes: 2
Reputation: 26
Which OS are you using ? im adding an example to open /dev/video0 and capture a frame on linux using the built in V4L2 (I am unfamiliar with the windows alternative)
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <sys/mman.h>
int main() {
int fd = open("/dev/video0", O_RDWR); // Open the video device
if (fd == -1) {
perror("Opening video device");
return 1;
}
struct v4l2_capability cap;
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
perror("Querying Capabilities");
return 1;
}
struct v4l2_format fmt;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; // Set format to MJPEG
fmt.fmt.pix.field = V4L2_FIELD_NONE;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
perror("Setting Pixel Format");
return 1;
}
struct v4l2_requestbuffers req;
req.count = 1; // Request a single buffer
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {
perror("Requesting Buffer");
return 1;
}
struct v4l2_buffer buf;
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if (ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) {
perror("Querying Buffer");
return 1;
}
void* buffer = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
if (buffer == MAP_FAILED) {
perror("mmap");
return 1;
}
if (ioctl(fd, VIDIOC_STREAMON, &buf.type) == -1) {
perror("Stream On");
return 1;
}
// Queue the buffer
if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {
perror("Queue Buffer");
return 1;
}
// Dequeue the buffer
if (ioctl(fd, VIDIOC_DQBUF, &buf) == -1) {
perror("Dequeue Buffer");
return 1;
}
FILE* out = fopen("capture.jpg", "wb");
if (!out) {
perror("Cannot open image");
return 1;
}
fwrite(buffer, buf.bytesused, 1, out); // Save buffer to JPEG
fclose(out);
munmap(buffer, buf.length);
close(fd);
return 0;
}
Ive used this for a MATLAB project, to capture and analyse binning of pixels on a certain display and camera. I hope it helps
Upvotes: 1