first attempt to measure the level

master
Steffen Pohle 3 years ago
parent 3d0f06d414
commit e51289b772

@ -91,6 +91,8 @@ Video *vid_open(char *name) {
}
}
vid_getctrls(video);
return video;
}
@ -324,3 +326,32 @@ int vid_stop(Video* video) {
return 0;
};
void vid_getctrls (Video* video) {
int i, j;
struct v4l2_queryctrl queryctrl;
memset (&queryctrl, 0, sizeof (queryctrl));
for (j = 0, i = V4L2_CID_BASE; i < V4L2_CID_DETECT_CLASS_BASE+0x1000; i++) {
queryctrl.id = i;
if (0 == ioctl (video->fd, VIDIOC_QUERYCTRL, &queryctrl)) {
if (j == 0) video->ctrl_bright = queryctrl.id;
else if (j == 1) video->ctrl_contrast = queryctrl.id;
j++;
}
}
};
void vid_setctrls (Video* video, int bright, int contrast) {
struct v4l2_control ctrl;
CLEAR(ctrl);
ctrl.id = video->ctrl_bright;
ctrl.value = bright;
xioctl (video->fd, VIDIOC_S_CTRL, &ctrl);
CLEAR(ctrl);
ctrl.id = video->ctrl_contrast;
ctrl.value = contrast;
xioctl (video->fd, VIDIOC_S_CTRL, &ctrl);
};

@ -135,6 +135,28 @@ void image_draw_rect (ImageRaw *img, Rect *r, int col) {
}
void image_get_minmax (ImageRaw *img, Rect *r, int *min, int *max) {
int x, y, l, cr, cg, cb;
if (img == NULL || img->data == NULL) return;
cr = (unsigned char)*(img->data+0+3*(r->x+r->y*img->w));
cg = (unsigned char)*(img->data+1+3*(r->x+r->y*img->w));
cb = (unsigned char)*(img->data+2+3*(r->x+r->y*img->w));
*min = *max = cr + cg + cb;
for (x = r->x; x < (r->x+r->w) && x < img->w; x++)
for (y = r->y; y < (r->w + r->h) && y < img->h; y++) {
cr = (unsigned char)*(img->data+0+3*(x+y*img->w));
cg = (unsigned char)*(img->data+1+3*(x+y*img->w));
cb = (unsigned char)*(img->data+2+3*(x+y*img->w));
// printf ("%d %d %d\n", cr, cg, cb);
l = cr + cg + cb;
if (l < *min) *min = l;
if (l > *max) *max = l;
}
}
ImageFloat *imageF_alloc (int w, int h) {
ImageFloat *i = NULL;

@ -14,6 +14,8 @@ int conf_samples = 25;
int conf_rotate = 0;
Rect conf_rect = { .x = 315, .y = 0, .w = 70, .h = 1910 };
int detect_level(ImageFloat *imgf);
/*
* open video device
* read multiple images into memory
@ -45,7 +47,7 @@ int main(int argc, char **argv) {
char outdate[LEN_FILENAME];
time_t curtime = time(NULL);
struct tm *curtime_tm = NULL;
int i;
int i, c, b, level, cont, bright, min, max;
// for debugging only
curtime_tm = localtime(&curtime);
@ -92,9 +94,38 @@ int main(int argc, char **argv) {
// printf ("vidoiltank\n");
// printf (" device: %s (%d x %d)\n", conf_devname, conf_width, conf_height);
//
// open video device
if ((video = vid_open("/dev/video0")) == NULL) return -1;
if (vid_start(video, conf_iomode, conf_width, conf_height) == -1) return -1;
//
// search for god brightness and contrast
printf ("check controls\n");
cont = 200; // just picked some random numbers
bright = 170; // just picked some random numbers
for (level = 0, c = 32; c <= 250; c += 64)
for (b = 32; b <= 250; b += 64) {
vid_setctrls(video, b, c);
do {} while ((tmpimg = vid_grabimage(video, img)) == NULL && errno == EAGAIN);
if (tmpimg == NULL) {
printf ("could not grab image\n");
exit(1);
}
img = tmpimg;
image_get_minmax (img, &conf_rect, &min, &max);
if (max-min > level) {
cont = c;
bright = b;
level = max-min;
}
}
printf ("found best control: contrast: %d brightness: %d\n", cont, bright);
vid_setctrls(video, bright, cont);
//
// get samples
printf ("Read Samples\n");
for (i = 0; i < conf_samples; i++) {
do {} while ((tmpimg = vid_grabimage(video, img)) == NULL && errno == EAGAIN);
if (tmpimg == NULL) {
@ -110,7 +141,7 @@ int main(int argc, char **argv) {
}
if (i == 0) {
snprintf (fn, 3*LEN_FILENAME, "%s/%s-img-%02d.jpg", conf_debugout, outdate, i);
snprintf (fn, 3*LEN_FILENAME, "%s/%s-img-%02d-%02d.jpg", conf_debugout, outdate, bright, cont);
image_draw_rect(img, &conf_rect, 0x00FFFF);
image_save(img, fn, 98);
}
@ -123,8 +154,63 @@ int main(int argc, char **argv) {
snprintf (fn, 3*LEN_FILENAME, "%s/%s-imgf-%03d.jpg", conf_debugout, outdate, conf_samples);
image_save(tmpimg, fn, 98);
level = detect_level(imgf);
tmpimg = image_copyF(imgf);
Rect r = {.x = 0, .y = level, .w = 10, .h = 1};
image_draw_rect(tmpimg, &r, 0x0000FF00);
snprintf (fn, 3*LEN_FILENAME, "%s/%s-img-data.jpg", conf_debugout, outdate);
image_save(tmpimg, fn, 98);
printf ("%s Found Level: %5.2f Y-Pos: %d\n", outdate, 100.0 * (1.0-(float)level/(float)imgf->h), level);
return 0;
};
int detect_level(ImageFloat *imgf) {
int y, x, ylow, level;
float v = 0.0, vmin, vmax;
//
// calculate average, and save value in left row
for (y = 0; y < imgf->h; y++) {
for (v = 0.0, x = 0; x < imgf->w; x++)
v += imgf->data[x + y * imgf->w];
v = v / (float) x;
if (y == 0) vmin = vmax = v;
if (vmin > v) vmin = v;
if (vmax < v) vmax = v;
// save result in the top left position,
// together with a bar for display
imgf->data[y * imgf->w] = v;
}
//
// normalize 0.0 .. 1.0
for (y = 0; y < imgf->h; y++) for (x = 0; x < imgf->w; x++) {
imgf->data[x + y * imgf->w] = (imgf->data[x + y * imgf->w]-vmin)/(vmax-vmin);
}
//
// search for the level from below
vmin = 1.0;
vmax = 0.0;
int avg = 8;
level = 0;
for (ylow = 0; ylow < imgf->h; ylow++) {
if (ylow == 0) v = imgf->data[(ylow) * imgf->w];
v = ((float)avg-1.0) * v/(float)avg + imgf->data[(ylow) * imgf->w]/(float) avg;
for (x = 0; x < 8; x++) imgf->data[x + (ylow) * imgf->w] = v;
}
for (ylow = imgf->h - 1; ylow >= 0; ylow--) {
if (ylow == imgf->h - 1) v = imgf->data[(ylow) * imgf->w];
v = ((float)avg-1.0) * v/(float)avg + imgf->data[(ylow) * imgf->w]/(float) avg;
for (x = 4; x < 16; x++) imgf->data[x + (ylow) * imgf->w] = v;
if (v < 0.1) level = ylow;
}
return level;
};

@ -74,6 +74,9 @@ struct s_video {
struct v4l2_crop crop;
struct v4l2_format fmt;
unsigned int ctrl_bright;
unsigned int ctrl_contrast;
} typedef Video;
@ -104,6 +107,7 @@ ImageFloat *imageF_alloc (int w, int h);
ImageFloat *imageF_copy(ImageRaw *iraw, Rect *r);
ImageRaw *image_copyF(ImageFloat *ifloat);
void imageF_add(ImageFloat *ifloat, ImageRaw *iraw, Rect *r);
void image_get_minmax (ImageRaw *img, Rect *r, int *min, int *max);
/* getvideo.c
*
@ -115,6 +119,7 @@ int vid_start(Video* video, int ionmode, int width, int height);
ImageRaw *vid_grabimage(Video* video, ImageRaw *img);
int vid_stop(Video* video);
void vid_close(Video* video);
void vid_getctrls (Video* video);
void vid_setctrls (Video* video, int bright, int contrast);
#endif

Loading…
Cancel
Save