mytakepic/takepic.c
2015-07-23 13:51:09 +03:00

504 lines
16 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "takepic.h"
#include "usage.h"
#ifdef USE_BTA
#include "bta_print.h"
#endif
#include <locale.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef USEPNG
int writepng(char *filename, int width, int height, void *data);
#endif /* USEPNG */
#define BUFF_SIZ 4096
#define TMBUFSIZ 40 // ÄÌÉÎÁ ÂÕÆÅÒÁ ÄÌÑ ÓÔÒÏËÉ Ó ×ÒÅÍÅÎÅÍ
char tm_buf[TMBUFSIZ]; // ÂÕÆÅÒ ÄÌÑ ÓÔÒÏËÉ Ó ×ÒÅÍÅÎÅÍ
u_int16_t max=0, min=65535; // ÜËÓÔÒÅÍÁÌØÎÙÅ ÚÎÁÞÅÎÉÑ ÔÅËÕÝÅÇÏ ÉÚÏÂÒÁÖÅÎÉÑ
double avr, std; // ÓÒÅÄÎÅÅ ÚÎÁÞÅÎÉÅ É ÓÒÅÄÎÅË×ÁÄÒÁÔÉÞÅÓËÏÅ ÏÔËÌÏÎÅÎÉÅ ÔÅËÕÝÅÇÏ ÉÚÏÂÒ.
char *camera = NULL, viewfield[80];
double pixX, pixY; // ÒÁÚÍÅÒ ÐÉËÓÅÌÑ
int numcams = 0;
void print_stat(u_int16_t *img, long size, FILE* f);
int itime(){ // ÕÓÌ. ×ÒÅÍÑ × ÓÅËÕÎÄÁÈ
struct timeval ct;
gettimeofday(&ct, NULL);
return (ct.tv_sec);
}
int time0;
int ltime(){ // ×ÒÅÍÑ, ÐÒÏÛÅÄÛÅÅ Ó ÍÏÍÅÎÔÁ ÚÁÐÕÓËÁ ÐÒÏÇÒÁÍÍÙ
return(itime()-time0);
}
size_t curtime(char *s_time){ // ÓÔÒÏËÁ - ÔÅËÕÝÅÅ ×ÒÅÍÑ/ÄÁÔÁ
time_t tm = time(NULL);
return strftime(s_time, TMBUFSIZ, "%d/%m/%Y,%H:%M:%S", localtime(&tm));
}
double t_ext, t_int; // ×ÎÅÛÎÑÑ Ô., Ô. ËÁÍÅÒÙ (+ ÎÁ ËÏÎÅà ÜËÓÐÏÚÉÃÉÉ)
time_t expStartsAt; // ×ÒÅÍÑ ÎÁÞÁÌÁ ÜËÓÐÏÚÉÃÉÉ (time_t)
int check_filename(char *buff, char *outfile, char *ext){
struct stat filestat;
int num;
for(num = 1; num < 10000; num++){
if(snprintf(buff, BUFF_SIZ, "%s_%04d.%s", outfile, num, ext) < 1)
return 0;
if(stat(buff, &filestat)) // ÆÁÊÌÁ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ
return 1;
}
return 0;
}
int main(int argc, char **argv){
int i; // ÄÌÑ ÃÉËÌÏ×
FILE *f_tlog = NULL;// ÆÁÊÌ, × ËÏÔÏÒÙÊ ÂÕÄÅÔ ÚÁÐÉÓÙ×ÁÔØÓÑ ÖÕÒÎÁÌ ÔÅÍÐÅÒÁÔÕÒ
FILE *f_statlog = NULL; // ÆÁÊÌ ÄÌÑ ÓÔÁÔÉÓÔÉËÉ × ÒÅÖÉÍÅ "ÔÏÌØËÏ ÓÔÁÔÉÓÔÉËÁ"
char libver[LIBVERSIZ]; // ÂÕÆÅÒ ÄÌÑ ×ÅÒÓÉÉ ÂÉÂÌÉÏÔÅËÉ fli
cam_t *cam = NULL; // ÓÐÉÓÏË ËÁÍÅÒ
setlocale(LC_ALL, getenv("LC_ALL"));
setlocale(LC_NUMERIC, "C");
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
//bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
textdomain(GETTEXT_PACKAGE);
parse_args(argc, argv);
//TRYFUNC(FLISetDebugLevel, NULL /* "NO HOST" */, FLIDEBUG_ALL);
TRYFUNC(FLISetDebugLevel, NULL, FLIDEBUG_NONE);
TRYFUNC(FLIGetLibVersion, libver, LIBVERSIZ);
// ÷ÅÒÓÉÑ ÂÉÂÌÉÏÔÅËÉ '%s'
info(_("Library version '%s'"), libver);
findcams(FLIDOMAIN_USB, &cam);
if(save_Tlog){
f_tlog = fopen("temp_log", "a");
// îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÆÁÊÌ ÖÕÒÎÁÌÁ ÔÅÍÐÅÒÁÔÕÒ
if(!f_tlog) err(1, _("Can't open temperature log file"));
fprintf(f_tlog, "\n\n\n");
}
if(stat_logging){
struct stat s;
char print_hdr = 1;
if(stat("stat_log", &s) == 0) print_hdr = 0;
f_statlog = fopen("stat_log", "a");
// îÅ ÍÏÇÕ ÏÔËÒÙÔØ ÆÁÊÌ ÖÕÒÎÁÌÁ ÓÔÁÔÉÓÔÉËÉ
if(!f_statlog) err(1, _("Can't open statistics log file"));
if(print_hdr)
fprintf(f_statlog, "Time\t\t\tUnix time\tTexp\tTint\tText\tImax\tImin\tIavr\tIstd\tNover\tN>3std\tIavr3\t\tIstd3\n");
}
i = 0;
for (i = 0; i < numcams; i++){
long x0,x1, y0,y1, row, img_rows, row_width, ltmp, img_size;
flidev_t dev;
char buff[BUFF_SIZ];
u_int16_t *img;
int j;
// ëÁÍÅÒÁ '%s' ÉÚ ÄÏÍÅÎÁ %s
info(_("Camera '%s', domain %s"), cam[i].name, cam[i].dname);
TRYFUNC(FLIOpen, &dev, cam[i].name, FLIDEVICE_CAMERA | cam[i].domain);
if(r) continue;
TRYFUNC(FLIGetModel, dev, buff, BUFF_SIZ);
// íÏÄÅÌØ:\t\t%s
info(_("Model:\t\t%s"), buff);
camera = strdup(buff);
TRYFUNC(FLIGetHWRevision, dev, &ltmp);
// áÐÐ. ×ÅÒÓÉÑ: %ld
info(_("HW revision: %ld"), ltmp);
TRYFUNC(FLIGetFWRevision, dev, &ltmp);
// ðÒÏÇÒ. ×ÅÒÓÉÑ: %ld
info(_("SW revision: %ld"), ltmp);
TRYFUNC(FLIGetPixelSize, dev, &pixX, &pixY);
// òÁÚÍÅÒ ÐÉËÓÅÌÑ: %g x %g
info(_("Pixel size: %g x %g"), pixX, pixY);
TRYFUNC(FLIGetVisibleArea, dev, &x0, &y0, &x1, &y1);
snprintf(viewfield, 79, "(%ld, %ld)(%ld, %ld)", x0, y0, x1, y1);
// ÷ÉÄÉÍÏÅ ÐÏÌÅ: %s
info(_("Field of view: %s"), viewfield);
if(X1 > x1) X1 = x1;
if(Y1 > y1) Y1 = y1;
TRYFUNC(FLIGetArrayArea, dev, &x0, &y0, &x1, &y1);
// ðÏÌÅ ÉÚÏÂÒÁÖÅÎÉÑ: (%ld, %ld)(%ld, %ld)
info(_("Array field: (%ld, %ld)(%ld, %ld)"), x0, y0, x1, y1);
TRYFUNC(FLISetHBin, dev, hbin);
TRYFUNC(FLISetVBin, dev, vbin);
if(X0 == -1) X0 = x0; // ÚÁÄÁÅÍ ÚÎÁÞÅÎÉÑ ÐÏ ÕÍÏÌÞÁÎÉÀ
if(Y0 == -1) Y0 = y0;
if(X1 == -1) X1 = x1;
if(Y1 == -1) Y1 = y1;
row_width = (X1 - X0) / hbin;
img_rows = (Y1 - Y0) / vbin;
//TRYFUNC(FLISetImageArea, dev, ltmp, tmp2, tmp3, tmp4);
TRYFUNC(FLISetImageArea, dev, X0, Y0,
X0 + (X1 - X0) / hbin, Y0 + (Y1 - Y0) / vbin);
TRYFUNC(FLISetNFlushes, dev, flushes);
if(set_T) TRYFUNC(FLISetTemperature, dev, temperature);
TRYFUNC(FLIGetTemperature, dev, &t_int);
// ôÅÍÐÅÒÁÔÕÒÁ (×ÎÕÔÒ.): %f
info(_("Inner temperature: %f"), t_int);
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_EXTERNAL, &t_ext);
// ôÅÍÐÅÒÁÔÕÒÁ (×ÎÅÛÎ.): %f
info(_("Outern temperature: %f"), t_ext);
if(only_T) continue;
TRYFUNC(FLISetExposureTime, dev, exptime);
TRYFUNC(FLISetFrameType, dev, frametype);
//TRYFUNC(FLISetBitDepth, dev, FLI_MODE_16BIT);
img_size = img_rows * row_width * sizeof(u_int16_t);
if((img = malloc(img_size)) == NULL) err(1, "malloc() failed");
for (j = 0; j < pics; j ++){
TRYFUNC(FLIGetTemperature, dev, &temperature); // ÔÅÍÐÅÒÁÔÕÒÁ ÄÏ ÎÁÞÁÌÁ ÜËÓÐÏÚÉÃÉÉ
printf("\n\n");
// úÁÈ×ÁÔ ËÁÄÒÁ %d\n
printf(_("Capture frame %d\n"), j);
TRYFUNC(FLIExposeFrame, dev);
expStartsAt = time(NULL); // ×ÒÅÍÑ ÎÁÞÁÌÁ ÜËÓÐÏÚÉÃÉÉ
if(save_Tlog) if(curtime(tm_buf))
// îÁÞÉÎÁÀ ÜËÓÐÏÚÉÃÉÀ %dÍÓ, ×ÒÅÍÑ: %s, ÆÁÊÌ: %s.%d.%d\n
fprintf(f_tlog, _("Begin exposition %dms, exptime: %s, filename: %s.%d.%d\n"),
exptime, tm_buf, outfile, i, j);
do{
TRYFUNC(FLIGetExposureStatus, dev, &ltmp);
if(r) break;
// %.3f ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÜËÓÐÏÚÉÃÉÉ\n
printf(_("%.3f seconds till exposition ends\n"), ((float)ltmp) / 1000.);
TRYFUNC(FLIGetTemperature, dev, &t_int);
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_EXTERNAL, &t_ext);
if(curtime(tm_buf)){
// ÄÁÔÁ/×ÒÅÍÑ
printf("%s: %s\tText=%.2f\tTint=%.2f\n", _("date/time"), tm_buf, t_ext, t_int);
if(save_Tlog) fprintf(f_tlog, "%s\t\t%.5f\t\t%.5f\n", tm_buf, t_ext, t_int);
}
else info("curtime() error");
if(ltmp > 10000) sleep(10);
else usleep(ltmp * 1000);
}while(ltmp);
// óÞÉÔÙ×ÁÎÉÅ ÉÚÏÂÒÁÖÅÎÉÑ:
printf(_("Read image: "));
int portion = 0;
for (row = 0; row < img_rows; row++){
TRYFUNC(FLIGrabRow, dev, &img[row * row_width], row_width);
if(r) break;
int progress = (int)(((float)row / (float)img_rows) * 100.);
if(progress/5 > portion){
if((++portion)%2) printf("..");
else printf("%d%%", portion*5);
fflush(stdout);
}
}
printf("100%%\n");
curtime(tm_buf);
if(f_statlog)
fprintf(f_statlog, "%s\t%ld\t%g\t%.2f\t%.2f\t", tm_buf, time(NULL), exptime/1000., t_int, t_ext);
print_stat(img, row_width * img_rows, f_statlog);
inline void WRITEIMG(int (*writefn)(char*,int,int,void*), char *ext){
if(!check_filename(buff, outfile, ext))
// îÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÆÁÊÌ
err(1, _("Can't save file"));
else{
TRYFUNC(writefn, buff, row_width, img_rows, img);
// æÁÊÌ ÚÁÐÉÓÁÎ × '%s'
if (r == 0) info(_("File saved as '%s'"), buff);
}
}
if(save_image){
#ifdef USERAW
WRITEIMG(writeraw, "raw");
#endif // USERAW
WRITEIMG(writefits, "fit");
#ifdef USEPNG
WRITEIMG(writepng, "png");
#endif /* USEPNG */
}
if(pause_len){
int delta;
time0 = itime();
while((delta = pause_len - ltime()) > 0){
// %d ÓÅËÕÎÄ ÄÏ ÏËÏÎÞÁÎÉÑ ÐÁÕÚÙ\n
printf(_("%d seconds till pause ends\n"), delta);
TRYFUNC(FLIGetTemperature, dev, &t_int);
TRYFUNC(FLIReadTemperature, dev, FLI_TEMPERATURE_EXTERNAL, &t_ext);
if(curtime(tm_buf)){
// ÄÁÔÁ/×ÒÅÍÑ
printf("%s: %s\tText=%.2f\tTint=%.2f\n", _("date/time"), tm_buf, t_ext, t_int);
if(save_Tlog) fprintf(f_tlog, "%s\t\t%.5f\t\t%.5f\n", tm_buf, t_ext, t_int);
}
else info("curtime() error");
if(delta > 10) sleep(10);
else sleep(delta);
}
}
}
free(camera);
free(img);
TRYFUNC(FLIClose, dev);
}
for (i = 0; i < numcams; i++)
free(cam[i].name);
free(cam);
if(f_tlog) fclose(f_tlog);
if(f_statlog) fclose(f_statlog);
exit(0);
}
void findcams(flidomain_t domain, cam_t **cam){
long r;
char **tmplist;
TRYFUNC(FLIList, domain | FLIDEVICE_CAMERA, &tmplist);
if (tmplist != NULL && tmplist[0] != NULL){
int i, cams = 0;
for (i = 0; tmplist[i] != NULL; i++) cams++;
if ((*cam = realloc(*cam, (numcams + cams) * sizeof(cam_t))) == NULL)
err(1, "realloc() failed");
for (i = 0; tmplist[i] != NULL; i++) {
int j;
cam_t *tmpcam = *cam + i;
for (j = 0; tmplist[i][j] != '\0'; j++)
if (tmplist[i][j] == ';'){
tmplist[i][j] = '\0';
break;
}
tmpcam->domain = domain;
switch (domain){
case FLIDOMAIN_PARALLEL_PORT:
tmpcam->dname = "parallel port";
break;
case FLIDOMAIN_USB:
tmpcam->dname = "USB";
break;
case FLIDOMAIN_SERIAL:
tmpcam->dname = "serial";
break;
case FLIDOMAIN_INET:
tmpcam->dname = "inet";
break;
default:
tmpcam->dname = "Unknown domain";
break;
}
tmpcam->name = strdup(tmplist[i]);
}
numcams += cams;
}
// ëÁÍÅÒÙ ÎÅ ÎÁÊÄÅÎÙ!\n
else info(_("No cameras found!\n"));
TRYFUNC(FLIFreeList, tmplist);
return;
}
#ifdef USERAW
int writeraw(char *filename, int width, int height, void *data){
int fd, size, err;
if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )) == -1){
warn("open(%s) failed", filename);
return -errno;
}
size = width * height * sizeof(u_int16_t);
if ((err = write(fd, data, size)) != size){
warn("write() failed");
err = -errno;
}
else err = 0;
close(fd);
return err;
}
#endif // USERAW
/*
* ÷ ÛÁÐËÅ ÄÏÌÖÎÙ ÂÙÔØ:
* RATE / Readout rate (KPix/sec)
* GAIN / gain, e/ADU
* SEEING / Seeing ('')
* IMSCALE / Image scale (''/pix x ''/pix)
* CLOUDS / Clouds (%)
*/
int writefits(char *filename, int width, int height, void *data){
long naxes[2] = {width, height}, startTime;
double tmp = 0.0;
struct tm *tm_starttime;
char buf[80];
time_t savetime = time(NULL);
fitsfile *fp;
TRYFITS(fits_create_file, &fp, filename);
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
// FILE / Input file original name
WRITEKEY(fp, TSTRING, "FILE", filename, "Input file original name");
// ORIGIN / organization responsible for the data
WRITEKEY(fp, TSTRING, "ORIGIN", "SAO RAS", "organization responsible for the data");
// OBSERVAT / Observatory name
WRITEKEY(fp, TSTRING, "OBSERVAT", "Special Astrophysical Observatory, Russia", "Observatory name");
// DETECTOR / detector
if(camera){
WRITEKEY(fp, TSTRING, "DETECTOR", camera, "Detector model");
}
// INSTRUME / Instrument
if(instrument){
WRITEKEY(fp, TSTRING, "INSTRUME", instrument, "Instrument");
}else
WRITEKEY(fp, TSTRING, "INSTRUME", "direct imaging", "Instrument");
// BZERO / zero point in scaling equation
//WRITEKEY(fp, TDOUBLE, "BZERO", &tmp, "zero point in scaling equation");
// BSCALE / linear factor in scaling equation
//tmp = 1.0; WRITEKEY(fp, TDOUBLE, "BSCALE", &tmp, "linear factor in scaling equation");
snprintf(buf, 79, "%.g x %.g", pixX, pixY);
// PXSIZE / pixel size
WRITEKEY(fp, TSTRING, "PXSIZE", buf, "Pixel size in m");
WRITEKEY(fp, TSTRING, "VIEW_FIELD", viewfield, "Camera field of view");
// CRVAL1, CRVAL2 / Offset in X, Y
if(X0) WRITEKEY(fp, TINT, "CRVAL1", &X0, "Offset in X");
if(Y0) WRITEKEY(fp, TINT, "CRVAL2", &Y0, "Offset in Y");
if(exptime == 0) sprintf(buf, "bias");
else if(frametype == FLI_FRAME_TYPE_DARK) sprintf(buf, "dark");
else if(objtype) strncpy(buf, objtype, 79);
else sprintf(buf, "object");
// IMAGETYP / object, flat, dark, bias, scan, eta, neon, push
WRITEKEY(fp, TSTRING, "IMAGETYP", buf, "Image type");
// DATAMAX, DATAMIN / Max,min pixel value
WRITEKEY(fp, TUSHORT, "DATAMAX", &max, "Max pixel value");
WRITEKEY(fp, TUSHORT, "DATAMIN", &min, "Min pixel value");
WRITEKEY(fp, TDOUBLE, "DATAAVR", &avr, "Average pixel value");
WRITEKEY(fp, TDOUBLE, "DATASTD", &std, "Standart deviation of pixel value");
WRITEKEY(fp, TDOUBLE, "TEMP0", &temperature, "Camera temperature at exp. start (degr C)");
WRITEKEY(fp, TDOUBLE, "TEMP1", &t_int, "Camera temperature at exp. end (degr C)");
WRITEKEY(fp, TDOUBLE, "TEMPBODY", &t_ext, "Camera body temperature at exp. end (degr C)");
tmp = (temperature + t_int) / 2. + 273.15;
// CAMTEMP / Camera temperature (K)
WRITEKEY(fp, TDOUBLE, "CAMTEMP", &tmp, "Camera temperature (K)");
tmp = (double)exptime / 1000.;
// EXPTIME / actual exposition time (sec)
WRITEKEY(fp, TDOUBLE, "EXPTIME", &tmp, "actual exposition time (sec)");
// DATE / Creation date (YYYY-MM-DDThh:mm:ss, UTC)
strftime(buf, 79, "%Y-%m-%dT%H:%M:%S", gmtime(&savetime));
WRITEKEY(fp, TSTRING, "DATE", buf, "Creation date (YYYY-MM-DDThh:mm:ss, UTC)");
startTime = (long)expStartsAt;
tm_starttime = localtime(&expStartsAt);
strftime(buf, 79, "exposition starts at %d/%m/%Y, %H:%M:%S (local)", tm_starttime);
WRITEKEY(fp, TLONG, "UNIXTIME", &startTime, buf);
strftime(buf, 79, "%Y/%m/%d", tm_starttime);
// DATE-OBS / DATE (YYYY/MM/DD) OF OBS.
WRITEKEY(fp, TSTRING, "DATE-OBS", buf, "DATE OF OBS. (YYYY/MM/DD, local)");
strftime(buf, 79, "%H:%M:%S", tm_starttime);
// START / Measurement start time (local) (hh:mm:ss)
WRITEKEY(fp, TSTRING, "START", buf, "Measurement start time (hh:mm:ss, local)");
// OBJECT / Object name
if(objname){
WRITEKEY(fp, TSTRING, "OBJECT", objname, "Object name");
}
// BINNING / Binning
if(hbin != 1 || vbin != 1){
snprintf(buf, 79, "%d x %d", hbin, vbin);
WRITEKEY(fp, TSTRING, "BINNING", buf, "Binning (hbin x vbin)");
}
// OBSERVER / Observers
if(observers){
WRITEKEY(fp, TSTRING, "OBSERVER", observers, "Observers");
}
// PROG-ID / Observation program identifier
if(prog_id){
WRITEKEY(fp, TSTRING, "PROG-ID", prog_id, "Observation program identifier");
}
// AUTHOR / Author of the program
if(author){
WRITEKEY(fp, TSTRING, "AUTHOR", author, "Author of the program");
}
#ifdef USE_BTA
write_bta_data(fp);
#endif
TRYFITS(fits_write_img, fp, TUSHORT, 1, width * height, data);
TRYFITS(fits_close_file, fp);
return 0;
}
#ifdef USEPNG
int writepng(char *filename, int width, int height, void *data){
int err;
FILE *fp = NULL;
png_structp pngptr = NULL;
png_infop infoptr = NULL;
void *row;
if ((fp = fopen(filename, "wb")) == NULL){
err = -errno;
goto done;
}
if ((pngptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL)) == NULL){
err = -ENOMEM;
goto done;
}
if ((infoptr = png_create_info_struct(pngptr)) == NULL){
err = -ENOMEM;
goto done;
}
png_init_io(pngptr, fp);
png_set_compression_level(pngptr, Z_BEST_COMPRESSION);
png_set_IHDR(pngptr, infoptr, width, height, 16, PNG_COLOR_TYPE_GRAY,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT);
png_write_info(pngptr, infoptr);
png_set_swap(pngptr);
for(row = data; height > 0; row += width * sizeof(u_int16_t), height--)
png_write_row(pngptr, row);
png_write_end(pngptr, infoptr);
err = 0;
done:
if(fp) fclose(fp);
if(pngptr) png_destroy_write_struct(&pngptr, &infoptr);
return err;
}
#endif /* USEPNG */
void print_stat(u_int16_t *img, long size, FILE *f){
long i, Noverld = 0L, N = 0L;
double pv, sum=0., sum2=0., sz = (double)size, tres;
u_int16_t *ptr = img, val;
max = 0; min = 65535;
for(i = 0; i < size; i++, ptr++){
val = *ptr;
pv = (double) val;
sum += pv;
sum2 += (pv * pv);
if(max < val) max = val;
if(min > val) min = val;
if(val >= 65530) Noverld++;
}
// óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ\n
printf(_("Image stat:\n"));
avr = sum/sz;
printf("avr = %.1f, std = %.1f, Noverload = %ld\n", avr,
std = sqrt(fabs(sum2/sz - avr*avr)), Noverld);
printf("max = %u, min = %u, size = %ld\n", max, min, size);
// ÐÏÌÎÁÑ ÓÔÁÔÉÓÔÉËÁ, ÅÓÌÉ Õ ÎÁÓ ÒÅÖÉÍ ÓÏÈÒÁÎÅÎÉÑ ÓÔÁÔÉÓÔÉËÉ:
if(!f) return;
// IÓÒÅÄÎÅÅ, IÓÉÇÍÁ, NÐÅÒÅËÏÐ
fprintf(f, "%d\t%d\t%.3f\t%.3f\t%ld\t", max, min, avr, std, Noverld);
Noverld = 0L;
ptr = img; sum = 0.; sum2 = 0.;
tres = avr + 3. * std; // ÐÏÒÏÇ ÐÏ ÍÁËÓÉÍÕÍÕ - 3 ÓÉÇÍÙ
for(i = 0; i < size; i++, ptr++){
val = *ptr;
pv = (double) val;
if(pv > tres){
Noverld++; // ÔÅÐÅÒØ ÜÔÏ - ËÏÌ-×Ï ÓÌÉÛËÏÍ ÑÒËÉÈ ÐÉËÓÅÌÅÊ
continue;
}
sum += pv;
sum2 += (pv * pv);
N++;
}
if(N == 0L){
fprintf(f, "err\n");
return;
}
sz = (double)N;
avr = sum/sz; std = sqrt(fabs(sum2/sz - avr*avr));
// NÂÏÌØÛÅ3ÓÉÇÍ, IÓÒÅÄÎÅÅ × ÐÒÅÄÅÌÁÈ 3ÓÉÇÍ, IÓÉÇÍÁ × ÐÒÅÄÅÌÁÈ 3ÓÉÇÍ
fprintf(f, "%ld\t%.3f\t%.3f\n", Noverld, avr, std);
fflush(f);
printf("Novr3 = %ld\n", Noverld);
}