Skip to content

Commit ff45c5e

Browse files
webcam_capture: grayscale 240x240
1 parent 549f554 commit ff45c5e

File tree

1 file changed

+25
-29
lines changed

1 file changed

+25
-29
lines changed

webcam_test/webcam_capture.c

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,48 +11,41 @@
1111
#define WIDTH 640
1212
#define HEIGHT 480
1313
#define NUM_BUFFERS 4
14+
#define OUTPUT_WIDTH 240
15+
#define OUTPUT_HEIGHT 240
1416

1517
// Global variables
1618
int fd = -1;
1719
struct v4l2_buffer buf;
1820
void *buffers[NUM_BUFFERS];
1921
size_t buffer_length;
2022

21-
// Convert YUYV to RGB for PPM output
22-
void yuyv_to_rgb(unsigned char *yuyv, unsigned char *rgb, int width, int height) {
23-
for (int i = 0; i < width * height; i++) {
24-
int index = i * 2;
25-
int y = yuyv[index];
26-
int u = yuyv[index + 1];
27-
int v = yuyv[index + 3];
28-
29-
int r = y + (1.402 * (v - 128));
30-
int g = y - (0.344 * (u - 128)) - (0.714 * (v - 128));
31-
int b = y + (1.772 * (u - 128));
32-
33-
r = r < 0 ? 0 : (r > 255 ? 255 : r);
34-
g = g < 0 ? 0 : (g > 255 ? 255 : g);
35-
b = b < 0 ? 0 : (b > 255 ? 255 : b);
36-
37-
rgb[i * 3 + 0] = r;
38-
rgb[i * 3 + 1] = g;
39-
rgb[i * 3 + 2] = b;
23+
// Convert YUYV to grayscale and downscale to 240x240
24+
void yuyv_to_grayscale_240x240(unsigned char *yuyv, unsigned char *gray, int in_width, int in_height) {
25+
// Downscale factors
26+
float x_ratio = (float)in_width / OUTPUT_WIDTH;
27+
float y_ratio = (float)in_height / OUTPUT_HEIGHT;
28+
29+
for (int y = 0; y < OUTPUT_HEIGHT; y++) {
30+
for (int x = 0; x < OUTPUT_WIDTH; x++) {
31+
// Nearest-neighbor interpolation
32+
int src_x = (int)(x * x_ratio);
33+
int src_y = (int)(y * y_ratio);
34+
int src_index = (src_y * in_width + src_x) * 2; // YUYV: 2 bytes per pixel
35+
gray[y * OUTPUT_WIDTH + x] = yuyv[src_index]; // Use Y component for grayscale
36+
}
4037
}
4138
}
4239

43-
// Save frame as PPM
44-
void save_ppm(const char *filename, unsigned char *data, int width, int height) {
40+
// Save grayscale frame as .raw
41+
void save_raw(const char *filename, unsigned char *data, int width, int height) {
4542
FILE *fp = fopen(filename, "wb");
4643
if (!fp) {
4744
perror("Cannot open file");
4845
return;
4946
}
50-
fprintf(fp, "P6\n%d %d\n255\n", width, height);
51-
unsigned char *rgb = malloc(width * height * 3);
52-
yuyv_to_rgb(data, rgb, width, height);
53-
fwrite(rgb, 1, width * height * 3, fp);
47+
fwrite(data, 1, width * height, fp); // Write raw grayscale data
5448
fclose(fp);
55-
free(rgb);
5649
}
5750

5851
int init_webcam(const char *device) {
@@ -158,8 +151,11 @@ int capture_frame(char *filename) {
158151
return -1;
159152
}
160153

161-
// Save frame
162-
save_ppm(filename, buffers[buf.index], WIDTH, HEIGHT);
154+
// Convert and save frame
155+
unsigned char *gray = malloc(OUTPUT_WIDTH * OUTPUT_HEIGHT);
156+
yuyv_to_grayscale_240x240(buffers[buf.index], gray, WIDTH, HEIGHT);
157+
save_raw(filename, gray, OUTPUT_WIDTH, OUTPUT_HEIGHT);
158+
free(gray);
163159

164160
// Requeue buffer
165161
if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) {
@@ -173,7 +169,7 @@ int capture_frame(char *filename) {
173169
int capture_frames(int n) {
174170
for (int i = 0; i < n; i++) {
175171
char filename[32];
176-
snprintf(filename, sizeof(filename), "frame_%03d.ppm", i);
172+
snprintf(filename, sizeof(filename), "frame_%03d.raw", i);
177173
if (capture_frame(filename) < 0) {
178174
printf("Failed to capture frame %d\n", i);
179175
return -1;

0 commit comments

Comments
 (0)