$ git clone https://librecgm.ion.nu/librecgm.git
commit 779c06506d3af25e2400af64cddc60b7ab1ae52e
Author: Alicia <...>
Date: Tue Sep 21 00:15:37 2021 +0200
Some fixes to make readings more accurate/reliable.
diff --git a/gui.c b/gui.c
index 7c9a398..184c2ad 100644
--- a/gui.c
+++ b/gui.c
@@ -74,7 +74,7 @@ static int updatecam(int** onlygrab)
img.rowstride=gdk_pixbuf_get_rowstride(img_);
img.pixstride=gdk_pixbuf_get_n_channels(img_);
memset(img.pixels, 255, img.h*img.rowstride); // Clear to white
- drawgraph(&img, /*210*/unit*10, 283, list);
+ drawgraph(&img, unit*10, 283, list);
gtk_image_set_from_pixbuf(display, img_);
return 0;
}
diff --git a/read.c b/read.c
index cbb4511..19d98c5 100644
--- a/read.c
+++ b/read.c
@@ -46,7 +46,7 @@ static int scanline(struct img* img, int* line, int max)
}
int xrange=(img->w+img->h)/500; // TODO: Scale by (abs(linew)+abs(lineh)) instead
int yrange=(img->w+img->h)/1000;
- for(x=0; x<linew; x++)
+ for(x=0; x<abs(linew); x++)
{
y=x*lineh/linew;
//printf("Pixel %i x %i\n", startx+x, starty+y);
@@ -58,6 +58,7 @@ static int scanline(struct img* img, int* line, int max)
{
unsigned char* p=pixel(img, line[0]+x+xi, line[1]+y+yi);
v+=p[0]+p[1]+p[2];
+ v+=abs(p[0]-p[1])+abs(p[1]-p[2])+abs(p[2]-p[0]); // Bonus brightness for colorfulness. The lines we seek are colorless and dark
}
}
if(v<dark){dark=v; darkest=x;}
@@ -74,7 +75,7 @@ static int scanline(struct img* img, int* line, int max)
// printf("darkest: %i (~%i mmol/10l)\n", darkest, darkest*210/linew);
line[2]=line[0]+darkest;
line[3]=line[1]+darkest*lineh/linew;
- return darkest*max/linew;
+ return -darkest*max/linew;
}
}else{
//printf("Scanning along Y\n");
@@ -89,7 +90,7 @@ static int scanline(struct img* img, int* line, int max)
}
int xrange=(img->w+img->h)/1000; // TODO: Scale by (abs(linew)+abs(lineh)) instead
int yrange=(img->w+img->h)/500;
- for(y=0; y<lineh; y++)
+ for(y=0; y<abs(lineh); y++)
{
x=y*linew/lineh;
//printf("Pixel %i x %i\n", startx+x, starty+y);
@@ -101,6 +102,7 @@ static int scanline(struct img* img, int* line, int max)
{
unsigned char* p=pixel(img, line[0]+x+xi, line[1]+y+yi);
v+=p[0]+p[1]+p[2];
+ v+=abs(p[0]-p[1])+abs(p[1]-p[2])+abs(p[2]-p[0]); // Bonus brightness for colorfulness. The lines we seek are colorless and dark
}
}
if(v<dark){dark=v; darkest=y;}
@@ -117,74 +119,103 @@ static int scanline(struct img* img, int* line, int max)
// printf("darkest: %i (~%i mmol/10l)\n", darkest, darkest*210/lineh);
line[2]=line[0]+darkest*linew/lineh;
line[3]=line[1]+darkest;
- return darkest*max/lineh;
+ return -darkest*max/lineh;
}
}
}
int* readgraph(struct img* img, int* rect, int max)
{
+ char debug=0; // TODO: Make togglable from commandline?
if(!rect){rect=findrect(img);}
int i;
-/*
- printf("Rectangle detected:\n");
- for(i=0; i<4; i++)
+ if(debug)
{
- printf(" %i x %i\n", rect[i*2], rect[i*2+1]);
+ printf("Rectangle detected:\n");
+ for(i=0; i<4; i++)
+ {
+ printf(" %i x %i\n", rect[i*2], rect[i*2+1]);
+ drawline(img, &rect[i*2], &rect[((i+1)%4)*2], 0xff0000);
+ }
}
-*/
// Find the bluest corner, i.e. the "Ok" button
int blue=0;
int tmpblue;
int bluest;
for(i=0; i<4; i++)
{
-// drawline(img, &rect[i*2], &rect[((i+1)%4)*2], 0xff0000);
// Find coordinates slightly inset from the corner
int* a=&rect[i*2];
int* b=&rect[((i+1)%4)*2];
int* c=&rect[((i+2)%4)*2];
int ok[]={(a[0]+b[0]*80+c[0])/82,
(a[1]+b[1]*80+c[1])/82};
-// drawline(img, ok, b, 0xff0000);
+ if(debug){drawline(img, ok, b, 0xff0000);}
int xi,yi;
- int range=(img->w+img->h)/1000;
+ int range=(img->w+img->h)/200;
for(yi=-range; yi<range; yi++)
{
if(ok[1]+yi<0){continue;}
+ tmpblue=0;
for(xi=-range; xi<range; xi++)
{
if(ok[0]+xi<0){continue;}
unsigned char* p=pixel(img, ok[0]+xi, ok[1]+yi);
- if((tmpblue=(p[2]-(p[1]+p[0])/2))>blue){blue=tmpblue; bluest=i+1;}
+ tmpblue+=(p[2]-(p[1]+p[0])/2);
}
+ if(tmpblue>blue){blue=tmpblue; bluest=(i+1)%4;}
}
}
-// printf("Corner %i appears to have the OK button\n", bluest);
+ if(debug)
+ {
+ printf("Corner %i appears to have the OK button\n", bluest);
+ int* a=&rect[(bluest-1)*2];
+ int* b=&rect[((bluest)%4)*2];
+ int* c=&rect[((bluest+1)%4)*2];
+ int ok[]={(a[0]+b[0]*80+c[0])/82,
+ (a[1]+b[1]*80+c[1])/82};
+ if(debug){drawline(img, ok, b, 0x00ff00);}
+ }
int right[]={rect[((bluest)%4)*2],
rect[((bluest)%4)*2+1],
rect[((bluest+1)%4)*2],
rect[((bluest+1)%4)*2+1]};
-// printf("Right: %i x %i to %i x %i\n", right[0], right[1], right[2], right[3]);
int left[]={rect[((bluest+2)%4)*2],
rect[((bluest+2)%4)*2+1],
rect[((bluest+3)%4)*2],
rect[((bluest+3)%4)*2+1]};
-// printf("Left: %i x %i to %i x %i\n", left[0], left[1], left[2], left[3]);
+ if(debug)
+ {
+ printf("Right: %i x %i to %i x %i\n", right[0], right[1], right[2], right[3]);
+ printf("Left: %i x %i to %i x %i\n", left[0], left[1], left[2], left[3]);
+ }
#define subline(a,b,p1,p2) {((a)[0]*(p2)+(a)[2]*(p1))/(p1+p2), ((a)[1]*(p2)+(a)[3]*(p1))/(p1+p2),\
((b)[0]*(p1)+(b)[2]*(p2))/(p1+p2), ((b)[1]*(p1)+(b)[3]*(p2))/(p1+p2)}
int top[]=subline(left, right, 8, 3);
int bottom[]=subline(right, left, 8, 4);
// int header[]=subline(top, bottom, 5, 24);
// int end[]=subline(top, bottom, 12, 1);
-// drawline(img, top, &top[2], 0xff0000);
-// drawline(img, bottom, &bottom[2], 0xff0000);
+ if(debug)
+ {
+ drawline(img, top, &top[2], 0xff0000);
+ drawline(img, bottom, &bottom[2], 0xff0000);
+ }
int* list=malloc(sizeof(int)*(12*29-65));
for(i=65; i<12*29; i++)
{
int slice[]=subline(top, bottom, i, 13*29-i);
list[i-65]=scanline(img, slice, max);
-// drawline(img, slice, &slice[2], 0xff0000);
+ }
+ if(debug)
+ {
+ for(i=65; i<12*29; i++)
+ {
+ int slice[]=subline(top, bottom, i, 13*29-i);
+ slice[0]=(slice[0]-slice[2])*list[i-65]/max+slice[2];
+ slice[1]=(slice[1]-slice[3])*list[i-65]/max+slice[3];
+ drawline(img, slice, &slice[2], 0xff0000);
+ }
+ writepnm(img, "read.pnm");
}
return list;
}