mirror of
https://github.com/eddyem/astrovideoguide_v3.git
synced 2025-12-06 10:45:10 +03:00
add median filter
This commit is contained in:
parent
9d76c96602
commit
4ef3ae7605
@ -285,10 +285,10 @@ static int setgain(_U_ float e){
|
|||||||
static int changeformat(frameformat *fmt){
|
static int changeformat(frameformat *fmt){
|
||||||
FNAME();
|
FNAME();
|
||||||
if(!isopened) return FALSE;
|
if(!isopened) return FALSE;
|
||||||
if(!setInt("Width", fmt->w)) return FALSE;
|
setInt("Width", fmt->w);
|
||||||
if(!setInt("Height", fmt->h)) return FALSE;
|
setInt("Height", fmt->h);
|
||||||
if(!setInt("OffsetX", fmt->xoff)) return FALSE;
|
setInt("OffsetX", fmt->xoff);
|
||||||
if(!setInt("OffsetY", fmt->yoff)) return FALSE;
|
setInt("OffsetY", fmt->yoff);
|
||||||
int64_values i;
|
int64_values i;
|
||||||
if(getInt("Width", &i)) fmt->w = i.val;
|
if(getInt("Width", &i)) fmt->w = i.val;
|
||||||
if(getInt("Height", &i)) fmt->h = i.val;
|
if(getInt("Height", &i)) fmt->h = i.val;
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include "grasshopper.h"
|
#include "grasshopper.h"
|
||||||
#include "imagefile.h"
|
#include "imagefile.h"
|
||||||
#include "improc.h"
|
#include "improc.h"
|
||||||
|
#include "median.h"
|
||||||
|
|
||||||
// pointer to selected camera
|
// pointer to selected camera
|
||||||
static camera *theCam = NULL;
|
static camera *theCam = NULL;
|
||||||
@ -102,16 +103,17 @@ void camdisconnect(){
|
|||||||
|
|
||||||
static void calcexpgain(float newexp){
|
static void calcexpgain(float newexp){
|
||||||
DBG("recalculate exposition: oldexp=%g, oldgain=%g, newexp=%g", exptime, gain, newexp);
|
DBG("recalculate exposition: oldexp=%g, oldgain=%g, newexp=%g", exptime, gain, newexp);
|
||||||
if(newexp*1.25 > theconf.minexp){
|
while(newexp*1.25 > theconf.minexp){ // increase gain first
|
||||||
if(gain < gainmax - 1.){ // increase gain first
|
if(gain < gainmax - 0.9999){
|
||||||
gain += 1.;
|
gain += 1.;
|
||||||
newexp /= 1.25;
|
newexp /= 1.25;
|
||||||
|
}else break;
|
||||||
}
|
}
|
||||||
}else{ // make gain lower
|
while(newexp < theconf.minexp){
|
||||||
if(1.25*newexp < theconf.maxexp && gain > 1.){
|
if(1.25*newexp < theconf.maxexp && gain > 0.9999){
|
||||||
gain -= 1.;
|
gain -= 1.;
|
||||||
newexp *= 1.25;
|
newexp *= 1.25;
|
||||||
}
|
}else break;
|
||||||
}
|
}
|
||||||
if(newexp < theconf.minexp) newexp = theconf.minexp;
|
if(newexp < theconf.minexp) newexp = theconf.minexp;
|
||||||
else if(newexp > theconf.maxexp) newexp = theconf.maxexp;
|
else if(newexp > theconf.maxexp) newexp = theconf.maxexp;
|
||||||
@ -155,12 +157,12 @@ static void recalcexp(Image *I){
|
|||||||
if(sum100 > 100) break;
|
if(sum100 > 100) break;
|
||||||
}
|
}
|
||||||
DBG("Sum100=%d, idx100=%d", sum100, idx100);
|
DBG("Sum100=%d, idx100=%d", sum100, idx100);
|
||||||
if(idx100 > 200 && idx100 < 250) return; // good values
|
if(idx100 > 230 && idx100 < 253) return; // good values
|
||||||
if(idx100 > 250){ // exposure too long
|
if(idx100 > 253){ // exposure too long
|
||||||
calcexpgain(0.7*exptime);
|
calcexpgain(0.7*exptime);
|
||||||
}else{ // exposure too short
|
}else{ // exposure too short
|
||||||
if(idx100 > 5)
|
if(idx100 > 5)
|
||||||
calcexpgain(exptime * 210. / (float)idx100);
|
calcexpgain(exptime * 230. / (float)idx100);
|
||||||
else
|
else
|
||||||
calcexpgain(exptime * 50.);
|
calcexpgain(exptime * 50.);
|
||||||
}
|
}
|
||||||
@ -233,6 +235,14 @@ int camcapture(void (*process)(Image*)){
|
|||||||
brightness = theconf.brightness;
|
brightness = theconf.brightness;
|
||||||
}
|
}
|
||||||
if(process){
|
if(process){
|
||||||
|
if(theconf.medfilt){
|
||||||
|
Image *X = get_median(oIma, theconf.medseed);
|
||||||
|
if(X){
|
||||||
|
FREE(oIma->data);
|
||||||
|
FREE(oIma);
|
||||||
|
oIma = X;
|
||||||
|
}
|
||||||
|
}
|
||||||
process(oIma);
|
process(oIma);
|
||||||
}
|
}
|
||||||
FREE(oIma->data);
|
FREE(oIma->data);
|
||||||
|
|||||||
@ -56,7 +56,8 @@ configuration theconf = {
|
|||||||
.minexp=EXPOS_MIN - DBL_EPSILON,
|
.minexp=EXPOS_MIN - DBL_EPSILON,
|
||||||
.fixedexp=EXPOS_MIN,
|
.fixedexp=EXPOS_MIN,
|
||||||
.gain = 20.,
|
.gain = 20.,
|
||||||
.intensthres=DEFAULT_INTENSTHRES
|
.intensthres=DEFAULT_INTENSTHRES,
|
||||||
|
.medseed=MIN_MEDIAN_SEED,
|
||||||
};
|
};
|
||||||
|
|
||||||
// {"", PAR_DOUBLE, (void*)&theconf., 0},
|
// {"", PAR_DOUBLE, (void*)&theconf., 0},
|
||||||
@ -125,6 +126,14 @@ static confparam parvals[] = {
|
|||||||
"brightness value"},
|
"brightness value"},
|
||||||
{"starssort", PAR_INT, (void*)&theconf.starssort, 0, -DBL_EPSILON, 1.+DBL_EPSILON,
|
{"starssort", PAR_INT, (void*)&theconf.starssort, 0, -DBL_EPSILON, 1.+DBL_EPSILON,
|
||||||
"stars sorting algorithm: by distance from target (0) or by intensity (1)"},
|
"stars sorting algorithm: by distance from target (0) or by intensity (1)"},
|
||||||
|
{"medfilt", PAR_INT, (void*)&theconf.medfilt, 0, -DBL_EPSILON, 1.+DBL_EPSILON,
|
||||||
|
"use median filter"},
|
||||||
|
{"medseed", PAR_INT, (void*)&theconf.medseed, 0, MIN_MEDIAN_SEED-DBL_EPSILON, MAX_MEDIAN_SEED+DBL_EPSILON,
|
||||||
|
"median filter radius"},
|
||||||
|
{"fixedbg", PAR_INT, (void*)&theconf.fixedbkg, 0, -DBL_EPSILON, 1.+DBL_EPSILON,
|
||||||
|
"don't calculate background, use fixed value instead"},
|
||||||
|
{"fbglevel", PAR_INT, (void*)&theconf.fixedbkgval, 0, FIXED_BK_MIN-DBL_EPSILON, FIXED_BK_MAX+DBL_EPSILON,
|
||||||
|
"fixed background level"},
|
||||||
{NULL, 0, NULL, 0, 0., 0., NULL}
|
{NULL, 0, NULL, 0, 0., 0., NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,12 @@
|
|||||||
#define KUVMAX (5000.)
|
#define KUVMAX (5000.)
|
||||||
// default coefficient for corrections (move to Kdu, Kdv instead of du, dv)
|
// default coefficient for corrections (move to Kdu, Kdv instead of du, dv)
|
||||||
#define KCORR (0.97)
|
#define KCORR (0.97)
|
||||||
|
// min/max median seed
|
||||||
|
#define MIN_MEDIAN_SEED (1)
|
||||||
|
#define MAX_MEDIAN_SEED (7)
|
||||||
|
// fixed background
|
||||||
|
#define FIXED_BK_MIN (0)
|
||||||
|
#define FIXED_BK_MAX (250)
|
||||||
|
|
||||||
// exposition methods: 0 - auto, 1 - fixed
|
// exposition methods: 0 - auto, 1 - fixed
|
||||||
#define EXPAUTO (0)
|
#define EXPAUTO (0)
|
||||||
@ -78,6 +84,10 @@ typedef struct{
|
|||||||
int stpserverport; // steppers' server port
|
int stpserverport; // steppers' server port
|
||||||
int starssort; // stars sorting algorithm: by distance from target (0) or by intensity (1)
|
int starssort; // stars sorting algorithm: by distance from target (0) or by intensity (1)
|
||||||
int expmethod; // 0 - auto, 1 - fixed
|
int expmethod; // 0 - auto, 1 - fixed
|
||||||
|
int medfilt; // == 1 to make median filter before calculations
|
||||||
|
int medseed; // median seed
|
||||||
|
int fixedbkg; // don't calculate background, use fixed value instead
|
||||||
|
int fixedbkgval; // value of bk
|
||||||
// dU = Kxu*dX + Kyu*dY; dV = Kxv*dX + Kyv*dY
|
// dU = Kxu*dX + Kyu*dY; dV = Kxv*dX + Kyv*dY
|
||||||
double Kxu; double Kyu;
|
double Kxu; double Kyu;
|
||||||
double Kxv; double Kyv;
|
double Kxv; double Kyv;
|
||||||
|
|||||||
@ -128,18 +128,25 @@ Image *u8toImage(uint8_t *data, int width, int height, int stride){
|
|||||||
outp->width = width;
|
outp->width = width;
|
||||||
outp->height = height;
|
outp->height = height;
|
||||||
outp->dtype = FLOAT_IMG;
|
outp->dtype = FLOAT_IMG;
|
||||||
uint8_t min = *data, max = min;
|
/*
|
||||||
for(int y = 0; y < height; ++y){
|
int histogram[256] = {0};
|
||||||
uint8_t *ptr = &data[y*stride];
|
int wh = width*height;
|
||||||
for(int x = 0; x < width; ++x){
|
#pragma omp parallel
|
||||||
uint8_t p = *ptr++;
|
{
|
||||||
if(p < min) min = p;
|
int histogram_private[256] = {0};
|
||||||
else if(p > max) max = p;
|
#pragma omp for nowait
|
||||||
|
for(int i = 0; i < wh; ++i){
|
||||||
|
++histogram_private[data[i]];
|
||||||
|
}
|
||||||
|
#pragma omp critical
|
||||||
|
{
|
||||||
|
for(int i=0; i<256; ++i) histogram[i] += histogram_private[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outp->minval = (Imtype) min;
|
red("HISTO:\n");
|
||||||
outp->maxval = (Imtype) max;
|
for(int i = 0; i < 256; ++i) printf("%d:\t%d\n", i, histogram[i]);
|
||||||
//DBG("\nMAX=%g, MIN=%g\n", outp->maxval, outp->minval);
|
*/
|
||||||
|
|
||||||
outp->data = MALLOC(Imtype, width*height);
|
outp->data = MALLOC(Imtype, width*height);
|
||||||
// flip image updown for FITS coordinate system
|
// flip image updown for FITS coordinate system
|
||||||
OMP_FOR()
|
OMP_FOR()
|
||||||
@ -150,6 +157,7 @@ Image *u8toImage(uint8_t *data, int width, int height, int stride){
|
|||||||
*Out++ = (Imtype)(*In++);
|
*Out++ = (Imtype)(*In++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Image_minmax(outp);
|
||||||
return outp;
|
return outp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,27 +38,16 @@
|
|||||||
|
|
||||||
volatile atomic_ullong ImNumber = 0; // GLOBAL: counter of processed images
|
volatile atomic_ullong ImNumber = 0; // GLOBAL: counter of processed images
|
||||||
volatile atomic_bool stopwork = FALSE; // GLOBAL: suicide
|
volatile atomic_bool stopwork = FALSE; // GLOBAL: suicide
|
||||||
//int autoExposition = 1; // GLOBAL: ==1 if exposition calculation is auto
|
|
||||||
|
|
||||||
// GLOBAL: function to get stepper server status
|
|
||||||
char *(*stepstatus)(const char *messageid, char *buf, int buflen) = NULL;
|
|
||||||
// GLOBAL: set new status
|
|
||||||
char *(*setstepstatus)(const char *newstatus, char *buf, int buflen) = NULL;
|
|
||||||
// GLOBAL: move focus
|
|
||||||
char *(*movefocus)(const char *newstatus, char *buf, int buflen) = NULL;
|
|
||||||
// GLOBAL: get image information
|
// GLOBAL: get image information
|
||||||
char *(*imagedata)(const char *messageid, char *buf, int buflen);
|
char *(*imagedata)(const char *messageid, char *buf, int buflen) = NULL;
|
||||||
// GLOBAL: disconnect stepper server
|
|
||||||
void (*stepdisconnect)() = NULL;
|
steppersproc *theSteppers = NULL;
|
||||||
|
|
||||||
static FILE *fXYlog = NULL;
|
static FILE *fXYlog = NULL;
|
||||||
static double tstart = 0.; // time of logging start
|
static double tstart = 0.; // time of logging start
|
||||||
static double FPS = 0.; // frames per second
|
static double FPS = 0.; // frames per second
|
||||||
|
|
||||||
|
|
||||||
// function to process calculated corrections
|
|
||||||
static void (*proc_corr)(double, double) = NULL;
|
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
uint32_t area; // object area in pixels
|
uint32_t area; // object area in pixels
|
||||||
double Isum; // total object's intensity over background
|
double Isum; // total object's intensity over background
|
||||||
@ -150,16 +139,18 @@ static void getDeviation(object *curobj){
|
|||||||
xx /= theconf.naverage; yy /= theconf.naverage;
|
xx /= theconf.naverage; yy /= theconf.naverage;
|
||||||
Sx = sqrt(xsum2/theconf.naverage - xx*xx);
|
Sx = sqrt(xsum2/theconf.naverage - xx*xx);
|
||||||
Sy = sqrt(ysum2/theconf.naverage - yy*yy);
|
Sy = sqrt(ysum2/theconf.naverage - yy*yy);
|
||||||
green("\n\n\n Average centroid: X=%g (+-%g), Y=%g (+-%g)\n", xx, Sx, yy, Sy);
|
#ifdef EBUG
|
||||||
|
green("\n Average centroid: X=%g (+-%g), Y=%g (+-%g)\n", xx, Sx, yy, Sy);
|
||||||
|
#endif
|
||||||
LOGDBG("getDeviation(): Average centroid: X=%g (+-%g), Y=%g (+-%g)", xx, Sx, yy, Sy);
|
LOGDBG("getDeviation(): Average centroid: X=%g (+-%g), Y=%g (+-%g)", xx, Sx, yy, Sy);
|
||||||
averflag = 1;
|
averflag = 1;
|
||||||
if(fXYlog) fprintf(fXYlog, "%.1f\t%.1f\t%.1f\t%.1f", xx, yy, Sx, Sy);
|
if(fXYlog) fprintf(fXYlog, "%.1f\t%.1f\t%.1f\t%.1f", xx, yy, Sx, Sy);
|
||||||
process_corrections:
|
process_corrections:
|
||||||
if(proc_corr && averflag){
|
if(theSteppers && theSteppers->proc_corr && averflag){
|
||||||
if(Sx > XY_TOLERANCE || Sy > XY_TOLERANCE){
|
if(Sx > XY_TOLERANCE || Sy > XY_TOLERANCE){
|
||||||
LOGDBG("Bad value - not process"); // don't run processing for bad data
|
LOGDBG("Bad value - not process"); // don't run processing for bad data
|
||||||
}else
|
}else
|
||||||
proc_corr(xx, yy);
|
theSteppers->proc_corr(xx, yy);
|
||||||
}
|
}
|
||||||
XYnewline();
|
XYnewline();
|
||||||
}
|
}
|
||||||
@ -248,21 +239,24 @@ void process_file(Image *I){
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
DELTA("Labeling");
|
DELTA("Labeling");
|
||||||
printf("T%zd, N=%d\n", time(NULL), objctr);
|
DBG("T%zd, N=%d\n", time(NULL), objctr);
|
||||||
if(objctr > 1){
|
if(objctr > 1){
|
||||||
if(theconf.starssort)
|
if(theconf.starssort)
|
||||||
qsort(Objects, objctr, sizeof(object), compIntens);
|
qsort(Objects, objctr, sizeof(object), compIntens);
|
||||||
else
|
else
|
||||||
qsort(Objects, objctr, sizeof(object), compDist);
|
qsort(Objects, objctr, sizeof(object), compDist);
|
||||||
}
|
}
|
||||||
|
#ifdef EBUG
|
||||||
object *o = Objects;
|
object *o = Objects;
|
||||||
green("%6s\t%6s\t%6s\t%6s\t%6s\t%6s\t%6s\t%6s\n",
|
green("%6s\t%6s\t%6s\t%6s\t%6s\t%6s\t%6s\t%6s\t%8s\n",
|
||||||
"N", "Area", "Mv", "W/H", "Xc", "Yc", "Sx", "Sy");
|
"N", "Area", "Mv", "W/H", "Xc", "Yc", "Sx", "Sy", "Area/r^2");
|
||||||
for(int i = 0; i < objctr; ++i, ++o){
|
for(int i = 0; i < objctr; ++i, ++o){
|
||||||
// 1.0857 = 2.5/ln(10)
|
// 1.0857 = 2.5/ln(10)
|
||||||
printf("%6d\t%6d\t%6.1f\t%6.1f\t%6.1f\t%6.1f\t%6.1f\t%6.1f\n",
|
printf("%6d\t%6d\t%6.1f\t%6.1f\t%6.1f\t%6.1f\t%6.1f\t%6.1f\t%8.1f\n",
|
||||||
i, o->area, 20.-1.0857*log(o->Isum), o->WdivH, o->xc, o->yc, o->xsigma, o->ysigma);
|
i, o->area, 20.-1.0857*log(o->Isum), o->WdivH, o->xc, o->yc,
|
||||||
|
o->xsigma, o->ysigma, o->area/o->xsigma/o->ysigma);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
getDeviation(Objects); // calculate dX/dY and process corrections
|
getDeviation(Objects); // calculate dX/dY and process corrections
|
||||||
{ // prepare image and save jpeg
|
{ // prepare image and save jpeg
|
||||||
uint8_t *outp = NULL;
|
uint8_t *outp = NULL;
|
||||||
@ -381,11 +375,7 @@ void setpostprocess(const char *name){
|
|||||||
WARNX("Pusiserver unavailable, will check later");
|
WARNX("Pusiserver unavailable, will check later");
|
||||||
LOGWARN("Pusiserver unavailable, will check later");
|
LOGWARN("Pusiserver unavailable, will check later");
|
||||||
}
|
}
|
||||||
stepdisconnect = pusi_stop;
|
theSteppers = &pusyCANbus;
|
||||||
proc_corr = pusi_process_corrections;
|
|
||||||
stepstatus = pusi_status;
|
|
||||||
setstepstatus = set_pusistatus;
|
|
||||||
movefocus = set_pfocus;
|
|
||||||
}else{
|
}else{
|
||||||
WARNX("Unknown postprocess \"%s\"", name);
|
WARNX("Unknown postprocess \"%s\"", name);
|
||||||
LOGERR("Unknown postprocess \"%s\"", name);
|
LOGERR("Unknown postprocess \"%s\"", name);
|
||||||
|
|||||||
@ -32,12 +32,20 @@
|
|||||||
|
|
||||||
extern volatile atomic_bool stopwork;
|
extern volatile atomic_bool stopwork;
|
||||||
extern volatile atomic_ullong ImNumber;
|
extern volatile atomic_ullong ImNumber;
|
||||||
//extern int autoExposition;
|
|
||||||
extern char *(*stepstatus)(const char *messageid, char *buf, int buflen);
|
|
||||||
extern char *(*setstepstatus)(const char *newstatus, char *buf, int buflen);
|
|
||||||
extern char *(*movefocus)(const char *newstatus, char *buf, int buflen);
|
|
||||||
extern char *(*imagedata)(const char *messageid, char *buf, int buflen);
|
extern char *(*imagedata)(const char *messageid, char *buf, int buflen);
|
||||||
extern void (*stepdisconnect)();
|
|
||||||
|
typedef struct{
|
||||||
|
void (*proc_corr)(double, double);
|
||||||
|
char *(*stepstatus)(const char *messageid, char *buf, int buflen);
|
||||||
|
char *(*setstepstatus)(const char *newstatus, char *buf, int buflen);
|
||||||
|
char *(*movefocus)(const char *newstatus, char *buf, int buflen);
|
||||||
|
char *(*moveByU)(const char *val, char *buf, int buflen);
|
||||||
|
char *(*moveByV)(const char *val, char *buf, int buflen);
|
||||||
|
void (*stepdisconnect)();
|
||||||
|
} steppersproc;
|
||||||
|
|
||||||
|
extern steppersproc* theSteppers;
|
||||||
|
|
||||||
void process_file(Image *I);
|
void process_file(Image *I);
|
||||||
int process_input(InputType tp, char *name);
|
int process_input(InputType tp, char *name);
|
||||||
|
|||||||
@ -46,7 +46,7 @@ void signals(int sig){
|
|||||||
DBG("unlink(GP->pidfile)");
|
DBG("unlink(GP->pidfile)");
|
||||||
unlink(GP->pidfile);
|
unlink(GP->pidfile);
|
||||||
}
|
}
|
||||||
if(stepdisconnect) stepdisconnect();
|
if(theSteppers && theSteppers->stepdisconnect) theSteppers->stepdisconnect();
|
||||||
DBG("closeXYlog()");
|
DBG("closeXYlog()");
|
||||||
closeXYlog();
|
closeXYlog();
|
||||||
DBG("EXIT %d", sig);
|
DBG("EXIT %d", sig);
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "imagefile.h"
|
#include "imagefile.h"
|
||||||
#include "median.h"
|
#include "median.h"
|
||||||
|
|
||||||
@ -390,8 +391,8 @@ Image *get_median(const Image *img, int seed){
|
|||||||
* @retur 0 if error
|
* @retur 0 if error
|
||||||
*/
|
*/
|
||||||
int get_stat(const Image *in, int seed, Image **mean, Image **std){
|
int get_stat(const Image *in, int seed, Image **mean, Image **std){
|
||||||
if(!in) return 0;
|
if(!in) return FALSE;
|
||||||
if(seed < 1 || seed > (in->width - 1)/2 || seed > (in->height - 1)/2) return 0;
|
if(seed < 1 || seed > (in->width - 1)/2 || seed > (in->height - 1)/2) return FALSE;
|
||||||
#ifdef EBUG
|
#ifdef EBUG
|
||||||
double t0 = dtime();
|
double t0 = dtime();
|
||||||
#endif
|
#endif
|
||||||
@ -434,7 +435,7 @@ int get_stat(const Image *in, int seed, Image **mean, Image **std){
|
|||||||
*std = S;
|
*std = S;
|
||||||
}
|
}
|
||||||
DBG("time for mean/sigma computation: %gs", dtime() - t0);
|
DBG("time for mean/sigma computation: %gs", dtime() - t0);
|
||||||
return 1;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -445,14 +446,19 @@ int get_stat(const Image *in, int seed, Image **mean, Image **std){
|
|||||||
*/
|
*/
|
||||||
int calc_background(Image *img, Imtype *bk){
|
int calc_background(Image *img, Imtype *bk){
|
||||||
//DBG("image: min=%g, max=%g", img->minval, img->maxval);
|
//DBG("image: min=%g, max=%g", img->minval, img->maxval);
|
||||||
|
if(!img || !bk) return FALSE;
|
||||||
if(img->maxval - img->minval < DBL_EPSILON){
|
if(img->maxval - img->minval < DBL_EPSILON){
|
||||||
WARNX("Zero image!");
|
WARNX("Zero or overilluminated image!");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
if(theconf.fixedbkg){
|
||||||
|
*bk = theconf.fixedbkg;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
int w = img->width, h = img->height, wh = w*h;
|
int w = img->width, h = img->height, wh = w*h;
|
||||||
Imtype min = img->minval, ampl = img->maxval - min;
|
Imtype min = img->minval, ampl = img->maxval - min;
|
||||||
int histogram[256] = {0};
|
int histogram[256] = {0};
|
||||||
//DBG("min: %g, max: %g, ampl: %g", min, img->maxval, ampl);
|
DBG("min: %g, max: %g, ampl: %g", min, img->maxval, ampl);
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
{
|
{
|
||||||
int histogram_private[256] = {0};
|
int histogram_private[256] = {0};
|
||||||
@ -492,8 +498,8 @@ int calc_background(Image *img, Imtype *bk){
|
|||||||
//borderidx = (borderidx + modeidx) / 2;
|
//borderidx = (borderidx + modeidx) / 2;
|
||||||
Imtype borderval = ((Imtype)borderidx / 255.)*ampl + min;
|
Imtype borderval = ((Imtype)borderidx / 255.)*ampl + min;
|
||||||
if(bk) *bk = borderval;
|
if(bk) *bk = borderval;
|
||||||
// green("HISTO:\n");
|
//green("HISTO:\n");
|
||||||
// for(int i = 0; i < 256; ++i) printf("%d:\t%d\t%d\n", i, histogram[i], diff2[i]);
|
//for(int i = 0; i < 256; ++i) printf("%d:\t%d\t%d\n", i, histogram[i], diff2[i]);
|
||||||
// calculate values of upper 2% border
|
// calculate values of upper 2% border
|
||||||
#if 0
|
#if 0
|
||||||
Image *out = Image_sim(img);
|
Image *out = Image_sim(img);
|
||||||
|
|||||||
@ -114,6 +114,7 @@ static pthread_mutex_t sendmesg_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|||||||
|
|
||||||
// current steps counters (zero at the middle)
|
// current steps counters (zero at the middle)
|
||||||
static volatile atomic_int Uposition = 0, Vposition = 0, Fposition = 0;
|
static volatile atomic_int Uposition = 0, Vposition = 0, Fposition = 0;
|
||||||
|
static volatile atomic_int dUmove = 0, dVmove = 0;
|
||||||
static volatile atomic_bool Umoving = FALSE, Vmoving = FALSE, Fmoving = FALSE;
|
static volatile atomic_bool Umoving = FALSE, Vmoving = FALSE, Fmoving = FALSE;
|
||||||
static uint8_t fixerr = 0; // ==1 if can't fixed
|
static uint8_t fixerr = 0; // ==1 if can't fixed
|
||||||
|
|
||||||
@ -358,14 +359,14 @@ int pusi_connect(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stop processing & disconnect
|
// stop processing & disconnect
|
||||||
void pusi_stop(){
|
static void pusi_stop(){
|
||||||
pthread_join(processingthread, NULL);
|
pthread_join(processingthread, NULL);
|
||||||
pusi_disconnect();
|
pusi_disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// return TRUE if motor is stopped
|
// return TRUE if motor is stopped
|
||||||
static int moving_finished(const char *mesgstatus, volatile atomic_int *position){
|
static int moving_finished(const char *mesgstatus, volatile atomic_int *position){
|
||||||
double val;
|
double val = 0.;
|
||||||
char *ans = NULL;
|
char *ans = NULL;
|
||||||
int ret = TRUE;
|
int ret = TRUE;
|
||||||
if(send_message(mesgstatus, &ans) && getparval(PARstatus, ans, &val)){
|
if(send_message(mesgstatus, &ans) && getparval(PARstatus, ans, &val)){
|
||||||
@ -608,7 +609,7 @@ static int try2correct(double dX, double dY){
|
|||||||
* @param X, Y - centroid (x,y) in screen coordinate system
|
* @param X, Y - centroid (x,y) in screen coordinate system
|
||||||
* This function called from improc.c each time the corrections calculated (ONLY IF Xtarget/Ytarget > -1)
|
* This function called from improc.c each time the corrections calculated (ONLY IF Xtarget/Ytarget > -1)
|
||||||
*/
|
*/
|
||||||
void pusi_process_corrections(double X, double Y){
|
static void pusi_process_corrections(double X, double Y){
|
||||||
static bool coordstrusted = TRUE;
|
static bool coordstrusted = TRUE;
|
||||||
if(ismoving){ // don't process coordinates when moving
|
if(ismoving){ // don't process coordinates when moving
|
||||||
coordstrusted = FALSE;
|
coordstrusted = FALSE;
|
||||||
@ -644,7 +645,7 @@ static int pusi_setstate(pusistate newstate){
|
|||||||
|
|
||||||
// get current status (global variable stepstatus)
|
// get current status (global variable stepstatus)
|
||||||
// return JSON string with different parameters
|
// return JSON string with different parameters
|
||||||
char *pusi_status(const char *messageid, char *buf, int buflen){
|
static char *pusi_status(const char *messageid, char *buf, int buflen){
|
||||||
int l;
|
int l;
|
||||||
char *bptr = buf;
|
char *bptr = buf;
|
||||||
const char *s = NULL, *stage = NULL;
|
const char *s = NULL, *stage = NULL;
|
||||||
@ -723,7 +724,7 @@ typedef struct{
|
|||||||
pusistate state;
|
pusistate state;
|
||||||
} strstate;
|
} strstate;
|
||||||
// commands from client to change status
|
// commands from client to change status
|
||||||
strstate stringstatuses[] = {
|
static strstate stringstatuses[] = {
|
||||||
{"disconnect", PUSI_DISCONN},
|
{"disconnect", PUSI_DISCONN},
|
||||||
{"relax", PUSI_RELAX},
|
{"relax", PUSI_RELAX},
|
||||||
{"setup", PUSI_SETUP},
|
{"setup", PUSI_SETUP},
|
||||||
@ -734,7 +735,7 @@ strstate stringstatuses[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// try to set new status (global variable stepstatus)
|
// try to set new status (global variable stepstatus)
|
||||||
char *set_pusistatus(const char *newstatus, char *buf, int buflen){
|
static char *set_pusistatus(const char *newstatus, char *buf, int buflen){
|
||||||
strstate *s = stringstatuses;
|
strstate *s = stringstatuses;
|
||||||
pusistate newstate = PUSI_UNDEFINED;
|
pusistate newstate = PUSI_UNDEFINED;
|
||||||
while(s->str){
|
while(s->str){
|
||||||
@ -766,19 +767,6 @@ char *set_pusistatus(const char *newstatus, char *buf, int buflen){
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// change focus (global variable movefocus)
|
|
||||||
char *set_pfocus(const char *newstatus, char *buf, int buflen){
|
|
||||||
int newval = atoi(newstatus);
|
|
||||||
if(newval < theconf.minFpos || newval > theconf.maxFpos){
|
|
||||||
snprintf(buf, buflen, FAIL);
|
|
||||||
}else{
|
|
||||||
snprintf(buf, buflen, OK);
|
|
||||||
newfocpos = newval;
|
|
||||||
chfocus = TRUE;
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MAIN THREAD
|
// MAIN THREAD
|
||||||
static void *pusi_process_states(_U_ void *arg){
|
static void *pusi_process_states(_U_ void *arg){
|
||||||
FNAME();
|
FNAME();
|
||||||
@ -786,10 +774,11 @@ static void *pusi_process_states(_U_ void *arg){
|
|||||||
while(!stopwork){
|
while(!stopwork){
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
// check for moving
|
// check for moving
|
||||||
switch(state){
|
if(state == PUSI_DISCONN){
|
||||||
case PUSI_SETUP:
|
sleep(1);
|
||||||
case PUSI_GOTOTHEMIDDLE:
|
pusi_connect_server();
|
||||||
case PUSI_FIX:
|
continue;
|
||||||
|
}
|
||||||
if(moving_finished(Ustatus, &Uposition)) Umoving = FALSE;
|
if(moving_finished(Ustatus, &Uposition)) Umoving = FALSE;
|
||||||
else Umoving = TRUE;
|
else Umoving = TRUE;
|
||||||
if(moving_finished(Vstatus, &Vposition)) Vmoving = FALSE;
|
if(moving_finished(Vstatus, &Vposition)) Vmoving = FALSE;
|
||||||
@ -798,14 +787,6 @@ static void *pusi_process_states(_U_ void *arg){
|
|||||||
else Fmoving = TRUE;
|
else Fmoving = TRUE;
|
||||||
if(Umoving || Vmoving || Fmoving) ismoving = TRUE;
|
if(Umoving || Vmoving || Fmoving) ismoving = TRUE;
|
||||||
else ismoving = FALSE;
|
else ismoving = FALSE;
|
||||||
break;
|
|
||||||
case PUSI_DISCONN:
|
|
||||||
sleep(1);
|
|
||||||
pusi_connect_server();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(ismoving){
|
if(ismoving){
|
||||||
coordsRdy = FALSE;
|
coordsRdy = FALSE;
|
||||||
continue;
|
continue;
|
||||||
@ -817,6 +798,16 @@ static void *pusi_process_states(_U_ void *arg){
|
|||||||
moveF(delta); moveU(delta); moveV(delta);
|
moveF(delta); moveU(delta); moveV(delta);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if(dUmove){
|
||||||
|
moveU(dUmove);
|
||||||
|
dUmove = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(dVmove){
|
||||||
|
moveV(dVmove);
|
||||||
|
dVmove = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// if we are here, all U/V/F moving is finished
|
// if we are here, all U/V/F moving is finished
|
||||||
if(state != PUSI_DISCONN) first = TRUE;
|
if(state != PUSI_DISCONN) first = TRUE;
|
||||||
switch(state){ // pusirobo state machine
|
switch(state){ // pusirobo state machine
|
||||||
@ -871,3 +862,47 @@ static void *pusi_process_states(_U_ void *arg){
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// change focus (global variable movefocus)
|
||||||
|
static char *set_pfocus(const char *newstatus, char *buf, int buflen){
|
||||||
|
int newval = atoi(newstatus);
|
||||||
|
if(newval < theconf.minFpos || newval > theconf.maxFpos){
|
||||||
|
snprintf(buf, buflen, FAIL);
|
||||||
|
}else{
|
||||||
|
snprintf(buf, buflen, OK);
|
||||||
|
newfocpos = newval;
|
||||||
|
chfocus = TRUE;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
// move by U and V axis
|
||||||
|
static char *Umove(const char *val, char *buf, int buflen){
|
||||||
|
int d = atoi(val);
|
||||||
|
int Unfixed = Uposition + d + Fposition;
|
||||||
|
if(Unfixed > theconf.maxUsteps || Unfixed < -theconf.maxUsteps){
|
||||||
|
snprintf(buf, buflen, FAIL);
|
||||||
|
}
|
||||||
|
dUmove = d;
|
||||||
|
snprintf(buf, buflen, OK);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
static char *Vmove(const char *val, char *buf, int buflen){
|
||||||
|
int d = atoi(val);
|
||||||
|
int Vnfixed = Vposition + d + Fposition;
|
||||||
|
if(Vnfixed > theconf.maxVsteps || Vnfixed < -theconf.maxVsteps){
|
||||||
|
snprintf(buf, buflen, FAIL);
|
||||||
|
}
|
||||||
|
dVmove = d;
|
||||||
|
snprintf(buf, buflen, OK);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
steppersproc pusyCANbus = {
|
||||||
|
.stepdisconnect = pusi_stop,
|
||||||
|
.proc_corr = pusi_process_corrections,
|
||||||
|
.stepstatus = pusi_status,
|
||||||
|
.setstepstatus = set_pusistatus,
|
||||||
|
.movefocus = set_pfocus,
|
||||||
|
.moveByU = Umove,
|
||||||
|
.moveByV = Vmove,
|
||||||
|
};
|
||||||
|
|||||||
@ -19,17 +19,10 @@
|
|||||||
#ifndef PUSIROBO_H__
|
#ifndef PUSIROBO_H__
|
||||||
#define PUSIROBO_H__
|
#define PUSIROBO_H__
|
||||||
|
|
||||||
|
#include "improc.h"
|
||||||
|
|
||||||
|
extern steppersproc pusyCANbus;
|
||||||
|
|
||||||
// try to connect to local pusirobo server
|
// try to connect to local pusirobo server
|
||||||
int pusi_connect();
|
int pusi_connect();
|
||||||
// disconnect
|
|
||||||
void pusi_stop();
|
|
||||||
// global variable proc_corr
|
|
||||||
void pusi_process_corrections(double X, double Y);
|
|
||||||
// global variable stepstatus
|
|
||||||
char *pusi_status(const char *messageid, char *buf, int buflen);
|
|
||||||
// global variable setstepstatus
|
|
||||||
char *set_pusistatus(const char *newstatus, char *buf, int buflen);
|
|
||||||
// global variable movefocus
|
|
||||||
char *set_pfocus(const char *newstatus, char *buf, int buflen);
|
|
||||||
|
|
||||||
#endif // PUSIROBO_H__
|
#endif // PUSIROBO_H__
|
||||||
|
|||||||
@ -74,14 +74,21 @@ static getter getterHandlers[] = {
|
|||||||
|
|
||||||
static char *setstepperstate(const char *state, char *buf, int buflen);
|
static char *setstepperstate(const char *state, char *buf, int buflen);
|
||||||
static char *setfocusstate(const char *state, char *buf, int buflen);
|
static char *setfocusstate(const char *state, char *buf, int buflen);
|
||||||
//static char *setexposition(const char *expos, char *buf, int buflen);
|
static char *moveU(const char *val, char *buf, int buflen);
|
||||||
//static char *setexposmethod(const char *expos, char *buf, int buflen);
|
static char *moveV(const char *val, char *buf, int buflen);
|
||||||
static setter setterHandlers[] = {
|
static setter setterHandlers[] = {
|
||||||
{"stpstate", setstepperstate, "Set given steppers' server state"},
|
{"stpstate", setstepperstate, "Set given steppers' server state"},
|
||||||
{"focus", setfocusstate, "Move focus to given value"},
|
{"focus", setfocusstate, "Move focus to given value"},
|
||||||
|
{"moveU", moveU, "Relative moving by U axe"},
|
||||||
|
{"moveV", moveV, "Relative moving by V axe"},
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char *retFAIL(char *buf, int buflen){
|
||||||
|
snprintf(buf, buflen, FAIL);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
/**************** functions to process commands ****************/
|
/**************** functions to process commands ****************/
|
||||||
// getters
|
// getters
|
||||||
static char *helpmsg(_U_ const char *messageid, char *buf, int buflen){
|
static char *helpmsg(_U_ const char *messageid, char *buf, int buflen){
|
||||||
@ -107,28 +114,32 @@ static char *helpmsg(_U_ const char *messageid, char *buf, int buflen){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
static char *stepperstatus(const char *messageid, char *buf, int buflen){
|
static char *stepperstatus(const char *messageid, char *buf, int buflen){
|
||||||
if(stepstatus) return stepstatus(messageid, buf, buflen);
|
if(theSteppers && theSteppers->stepstatus) return theSteppers->stepstatus(messageid, buf, buflen);
|
||||||
snprintf(buf, buflen, FAIL);
|
return retFAIL(buf, buflen);
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
static char *getimagedata(const char *messageid, char *buf, int buflen){
|
static char *getimagedata(const char *messageid, char *buf, int buflen){
|
||||||
if(imagedata) return imagedata(messageid, buf, buflen);
|
if(imagedata) return imagedata(messageid, buf, buflen);
|
||||||
else snprintf(buf, buflen, FAIL);
|
return retFAIL(buf, buflen);
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
static char *setstepperstate(const char *state, char *buf, int buflen){
|
static char *setstepperstate(const char *state, char *buf, int buflen){
|
||||||
DBG("set steppersstate to %s", state);
|
DBG("set steppersstate to %s", state);
|
||||||
if(setstepstatus) return setstepstatus(state, buf, buflen);
|
if(theSteppers && theSteppers->setstepstatus) return theSteppers->setstepstatus(state, buf, buflen);
|
||||||
snprintf(buf, buflen, FAIL);
|
return retFAIL(buf, buflen);
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
static char *setfocusstate(const char *state, char *buf, int buflen){
|
static char *setfocusstate(const char *state, char *buf, int buflen){
|
||||||
DBG("move focus to %s", state);
|
DBG("move focus to %s", state);
|
||||||
if(movefocus) return movefocus(state, buf, buflen);
|
if(theSteppers && theSteppers->movefocus) return theSteppers->movefocus(state, buf, buflen);
|
||||||
snprintf(buf, buflen, FAIL);
|
return retFAIL(buf, buflen);
|
||||||
return buf;
|
}
|
||||||
|
static char *moveU(const char *val, char *buf, int buflen){
|
||||||
|
if(theSteppers && theSteppers->moveByU) return theSteppers->moveByU(val, buf, buflen);
|
||||||
|
return retFAIL(buf, buflen);
|
||||||
|
}
|
||||||
|
static char *moveV(const char *val, char *buf, int buflen){
|
||||||
|
if(theSteppers && theSteppers->moveByV) return theSteppers->moveByU(val, buf, buflen);
|
||||||
|
return retFAIL(buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user