int main(int c, char *v[]) { // read input arguments char *Hstring = pick_option(&c, &v, "h", ""); bool option_t = pick_option(&c, &v, "t", NULL); if (c != 5 && c!= 4 && c != 3) { return fprintf(stderr, "usage:\n\t%s" "width height [-h \"h1 ... h9\"] [clouds.gml [out.png]]\n", *v); // 1 2 3 4 } int out_width = atoi(v[1]); int out_height = atoi(v[2]); char *filename_clg = c > 3 ? v[3] : "-"; char *filename_out = c > 4 ? v[4] : "PNG:-"; // read input cloud file struct cloud_mask m[1]; if (option_t) read_cloud_mask_from_txt_file(m, filename_clg); else read_cloud_mask_from_gml_file(m, filename_clg); // acquire space for output image int w = out_width; int h = out_height; int *x = xmalloc(w*h*sizeof*x); for (int i = 0; i < w*h; i++) x[i] = 0; // scale the co-ordinates of the cloud if (*Hstring) { int nH; double *H = alloc_parse_doubles(9, Hstring, &nH); if (nH != 9) fail("can not read 3x3 matrix from \"%s\"", Hstring); cloud_mask_homography(m, H); free(H); } else cloud_mask_rescale(m, w, h); // draw mask over output image clouds_mask_fill(x, w, h, m); // save output image iio_save_image_int(filename_out, x, w, h); //cleanup free(x); free_cloud(m); return 0; }
int read_cloud_mask_from_txt_file(struct cloud_mask *m, char *filename) { m->n = 0; m->t = NULL; FILE *f = xfopen(filename, "r"); while (1) { int n, maxlin = 1000*12*4; char line[maxlin], *sl = fgets_until(line, maxlin, f, '\n'); if (!sl) break; struct cloud_polygon p; p.v = alloc_parse_doubles(maxlin, line, &p.n); p.n /= 2; cloud_add_polygon(m, p); } xfclose(f); m->low[0] = NAN; //update_uplow(m); return 0; }
// Obtain n numbers from string. // The string contains a list of ascii numbers // or the name of a file containing a list of ascii numbers. // In case of failure, unread numbers are set to zero. // Returns the number of read numbers. inline static int read_n_doubles_from_string(double *out, char *string, int n) { for (int i = 0; i < n; i++) out[i] = 0; int no; double *buf = NULL; FILE *f = fopen(string, "r"); if (f) { buf = read_ascii_doubles(f, &no); fclose(f); } else { buf = alloc_parse_doubles(n, string, &no); } if (no > n) no = n; for (int i = 0; i < no; i++) out[i] = buf[i]; free(buf); return no; }
int main(int c, char *v[]) { if (c < 6 || c > 48) { help(v[0]); return 1; } // utm zone and hemisphere: true for 'N' and false for 'S' int zone; bool hem; const char *utm_string = pick_option(&c, &v, "-utm-zone", "no_utm_zone"); parse_utm_string(&zone, &hem, utm_string); // ascii flag bool ascii = pick_option(&c, &v, "-ascii", NULL); // longitude-latitude bounding box double lon_m = atof(pick_option(&c, &v, "-lon-m", "-inf")); double lon_M = atof(pick_option(&c, &v, "-lon-M", "inf")); double lat_m = atof(pick_option(&c, &v, "-lat-m", "-inf")); double lat_M = atof(pick_option(&c, &v, "-lat-M", "inf")); // x-y bounding box double col_m = atof(pick_option(&c, &v, "-col-m", "-inf")); double col_M = atof(pick_option(&c, &v, "-col-M", "inf")); double row_m = atof(pick_option(&c, &v, "-row-m", "-inf")); double row_M = atof(pick_option(&c, &v, "-row-M", "inf")); // mask on the unrectified image grid const char *msk_orig_fname = pick_option(&c, &v, "-mask-orig", ""); int msk_orig_w, msk_orig_h; float *msk_orig = iio_read_image_float(msk_orig_fname, &msk_orig_w, &msk_orig_h); // rectifying homography double href_inv[9], hsec_inv[9]; int n_hom; const char *hom_string_ref = pick_option(&c, &v, "href", ""); if (*hom_string_ref) { double *hom = alloc_parse_doubles(9, hom_string_ref, &n_hom); if (n_hom != 9) fail("can not read 3x3 matrix from \"%s\"", hom_string_ref); invert_homography(href_inv, hom); } const char *hom_string_sec = pick_option(&c, &v, "hsec", ""); if (*hom_string_sec) { double *hom = alloc_parse_doubles(9, hom_string_sec, &n_hom); if (n_hom != 9) fail("can not read 3x3 matrix from \"%s\"", hom_string_sec); invert_homography(hsec_inv, hom); } // open disp and mask input images int w, h, nch, ww, hh, pd; float *dispy; float *dispx = iio_read_image_float_split(v[2], &w, &h, &nch); if (nch > 1) dispy = dispx + w*h; else dispy = calloc(w*h, sizeof(*dispy)); float *mask = iio_read_image_float(v[3], &ww, &hh); if (w != ww || h != hh) fail("disp and mask image size mismatch\n"); // open color images if provided uint8_t *clr = NULL; if (c > 6) { clr = iio_read_image_uint8_vec(v[6], &ww, &hh, &pd); if (w != ww || h != hh) fail("disp and color image size mismatch\n"); } // read input rpc models struct rpc rpc_ref[1], rpc_sec[1]; read_rpc_file_xml(rpc_ref, v[4]); read_rpc_file_xml(rpc_sec, v[5]); // outputs double p[2], q[2], X[3]; // count number of valid pixels, and determine utm zone int npoints = 0; for (int row=0; row<h; row++) for (int col=0; col<w; col++) { int pix = row*w + col; if (!mask[pix]) continue; // compute coordinates of pix in the full reference image double a[2] = {col, row}; apply_homography(p, href_inv, a); // check that it lies in the image domain bounding box if (round(p[0]) < col_m || round(p[0]) > col_M || round(p[1]) < row_m || round(p[1]) > row_M) continue; // check that it passes the image domain mask int x = (int) round(p[0]) - col_m; int y = (int) round(p[1]) - row_m; if ((x < msk_orig_w) && (y < msk_orig_h)) if (!msk_orig[y * msk_orig_w + x]) continue; // compute (lon, lat, alt) of the 3D point float dx = dispx[pix]; float dy = dispy[pix]; double b[2] = {col + dx, row + dy}; apply_homography(q, hsec_inv, b); intersect_rays(X, p, q, rpc_ref, rpc_sec); // check with lon/lat bounding box if (X[0] < lon_m || X[0] > lon_M || X[1] < lat_m || X[1] > lat_M) continue; // if it passed all these tests then it's a valid point npoints++; // if not defined, utm zone is that of the first point if (zone < 0) utm_zone(&zone, &hem, X[1], X[0]); } // print header for ply file FILE *ply_file = fopen(v[1], "w"); write_ply_header(ply_file, ascii, npoints, zone, hem, (bool) clr, false); // loop over all the pixels of the input disp map // a 3D point is produced for each non-masked disparity for (int row=0; row<h; row++) for (int col=0; col<w; col++) { int pix = row*w + col; if (!mask[pix]) continue; // compute coordinates of pix in the full reference image double a[2] = {col, row}; apply_homography(p, href_inv, a); // check that it lies in the image domain bounding box if (round(p[0]) < col_m || round(p[0]) > col_M || round(p[1]) < row_m || round(p[1]) > row_M) continue; // check that it passes the image domain mask int x = (int) round(p[0]) - col_m; int y = (int) round(p[1]) - row_m; if ((x < msk_orig_w) && (y < msk_orig_h)) if (!msk_orig[y * msk_orig_w + x]) continue; // compute (lon, lat, alt) of the 3D point float dx = dispx[pix]; float dy = dispy[pix]; double b[2] = {col + dx, row + dy}; apply_homography(q, hsec_inv, b); intersect_rays(X, p, q, rpc_ref, rpc_sec); // check with lon/lat bounding box if (X[0] < lon_m || X[0] > lon_M || X[1] < lat_m || X[1] > lat_M) continue; // convert (lon, lat, alt) to utm utm_alt_zone(X, X[1], X[0], zone); // colorization: if greyscale, copy the grey level on each channel uint8_t rgb[3]; if (clr) { for (int k = 0; k < pd; k++) rgb[k] = clr[k + pd*pix]; for (int k = pd; k < 3; k++) rgb[k] = rgb[k-1]; } // write to ply if (ascii) { fprintf(ply_file, "%0.17g %0.17g %0.17g ", X[0], X[1], X[2]); if (clr) fprintf(ply_file, "%d %d %d", rgb[0], rgb[1], rgb[2]); fprintf(ply_file, "\n"); } else { double XX[3] = {X[0], X[1], X[2]}; fwrite(XX, sizeof(double), 3, ply_file); if (clr) { unsigned char C[3] = {rgb[0], rgb[1], rgb[2]}; fwrite(rgb, sizeof(unsigned char), 3, ply_file); } } } fclose(ply_file); return 0; }