int main(int c, char *v[]) { if (c != 8) { fprintf(stderr, "usage:\n\t" "%s inpat.png first last sigma side nwarps epsilon\n", *v); // 0 1 2 3 4 5 6 7 return EXIT_FAILURE; } char *inpat = v[1]; int first_frame = atoi(v[2]); int last_frame = atoi(v[3]); float sigma = atof(v[4]); int side = atoi(v[5]); int nwarps = atoi(v[6]); float epsilon = atof(v[7]); int w, h, n; float **x = read_images(&n, &w, &h, inpat, first_frame, last_frame); assert(n == abs(first_frame - last_frame)); float *y = xmalloc(w * h * sizeof*y); frakes_monaco_smith(y, x, w, h, n, sigma, side, nwarps, epsilon); iio_save_image_float("-", y, w, h); for (int i = 0; i < n; i++) free(x[i]); free(x); free(y); return EXIT_SUCCESS; }
/*----------------------------------------------------------------------------*/ int main(int argc, char ** argv) { printf("INFO parameters use: \nlength_threshold sampling_factor <input1.pgm> [input2.pgm...] <polyout_filename> \n"); printf("=======================\n \n"); /* Detect the lines from the input images. Push the data into DistortedLines */ int idx_begin = 3, idx_end = argc-2; int w, h; DistortedLines<double> distLines; read_images(distLines, w, h, argc, argv, idx_begin, idx_end); /* Distortion correction: calcualte the polynomial parameters */ printf("\n Incremental LMA for distortion polynomial... \n"); double xp = (double)w/2+0.2, yp = (double)h/2+0.2; /* +0.2 - to avoid integers */ const int order = 11; const int inc = 2; /* increment; only odd orders will be taken */ vector<double> poly_params = incLMA <double> (distLines, order, inc, xp, yp); printf("\n Incremental LMA done. The polynomial was obtained. \n"); /* Get an inverse polynomial */ printf("\n Distortion correction polynomial... "); fflush(stdout); vector<double> poly_params_inv = polyInv<double>(poly_params, order, order, w, h, xp, yp); printf("done. \n"); /* Save the correction polynomial to output file */ printf("\n Saving polynomial to file... "); fflush(stdout); save_poly(argv[argc-1], poly_params_inv, order, order); printf("done. \n"); return EXIT_SUCCESS; }
stitcher::stitcher( string p_file_name, string p_prime_file_name, const unsigned int num_points_get, string output_mosaic_name ) { this->p_file_name = p_file_name; this->p_prime_file_name = p_prime_file_name; this->num_points_get = num_points_get; this->output_mosaic_name = output_mosaic_name; //num_points_div_2 = num_points / 2; //No point in doing everything else if images don't load, so try it first read_images(); //Determine which image coordinates are largest and use that //information when creating the combined image and other tasks if(p_image.rows > p_prime_image.rows) { image_y_max = p_image.rows; } else { image_y_max = p_prime_image.rows; } if(p_image.cols > p_prime_image.cols) { image_x_max = p_image.cols; } else { image_x_max = p_prime_image.cols; } //Setup vectors for correspondence points p_normalized_points.resize( num_points_get); p_prime_normalized_points.resize( num_points_get ); p_raw_points.resize( num_points_get ); p_prime_raw_points.resize( num_points_get ); //Setup matrices for homography A_matrix.create( num_points * 2, 9, CV_64FC1 ); H_matrix.create( 3, 3, CV_64FC1 ); H_vector.create( 9, 1, CV_64FC1 ); //initialize class members p_alpha = 0.0; p_mu_x = 0.0; p_mu_y = 0.0; p_prime_alpha = 0.0; p_prime_mu_x = 0.0; p_prime_mu_y = 0.0; }
void start_wall(){ current_dir = malloc(40); style = malloc(20); read_config(current_dir, style, &time_gap); int pid = fork(); if(!pid){ while(1){ read_images(); sleep(time_gap); } }else{ write_pid(pid); } }
int main(int argc, char *argv[]) { /// MPI-related variables int P, p, N, *Ip, I, dot_idx; double start_time, end_time; FILE *fp; /// Initialize MPI MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &P); MPI_Comm_rank(MPI_COMM_WORLD, &p); /// Problem size in this algorithm is No. of SLICES ========================== /// Input parameters are the index of the input image that is going to be used /// and the number of slices. if (argc < 3) { std::cout << "NOT ENOUGH INPUT PARAMETERS:\n./excutable image_num num_of_slices\n"; exit(1); } dot_idx = atoi(argv[1]); N = atoi(argv[2]); start_time = MPI_Wtime(); /// LOCAL SIZE =============================================================== Ip = new int[P]; // Number of elements of every processor for (int i = 0; i < P; i++) { Ip[i] = (N + P - i - 1) / P; } I = Ip[p]; // Number of elements for current processor /// READ IMAGES ============================================================== std::vector<cv::Mat> images = read_images(I, dot_idx); for (size_t i = 1; i < images.size(); i++) { if (images[0].rows != images[i].rows || images[0].cols != images[i].cols) { std::cout << "ERROR: Images need to be of the same size\n"; return -1; } } if (p == 0) { //. Print the experiment's parameters [DEBUGGING] printf ("%d, %d, %d\n", P, N, images[0].rows); } /// RESHAPE IMAGES =========================================================== int number_of_pixels = 0; for (int i = 0; i < I; i++) { number_of_pixels += images[i].rows * images[i].cols; } cv::Mat pixel_values; for (int i = 0; i < I; i++) { cv::Mat temp; images[i].reshape(1, images[i].rows * images[i].cols).copyTo(temp); pixel_values.push_back(temp); } pixel_values.convertTo(pixel_values, CV_32F); /// DO K-MEANS =============================================================== cv::Mat bestLabels; cv::kmeans(pixel_values, K, bestLabels, cv::TermCriteria(), 10, cv::KMEANS_RANDOM_CENTERS); std::vector<cv::Mat> clustered_images; /// bestLabels, contains the number of the cluster to which each pixel belongs int so_far = 0; for (int i = 0; i < I; i++) { cv::Mat temp; bestLabels.rowRange(so_far, so_far + images[i].rows * images[i].cols) .copyTo(temp); so_far += images[i].rows * images[i].cols; // cv::Mat new_temp; temp = temp.reshape(1, images[i].rows); clustered_images.push_back(temp); } std::vector<cv::Rect> blobs; std::vector<int> blob_count; std::vector<int> image_count; three_d_connected_components(clustered_images, blobs, image_count, blob_count); for (size_t i = 0; i < blob_count.size(); i++) { blob_count[i] -= K; } /// SHOW IMAGES (only for debugging purposes) ================================ for (int i = 0; i < N; i++) { /// Draw rectangles on image for (size_t r = 0; r < image_count.size(); r++) { if (image_count[r] == i) { rectangle(images[i], blobs[r], cv::Scalar(0, 0, 0), 1); std::ostringstream txt; txt << blob_count[r]; cv::Point origin(blobs[r].x + blobs[r].width / 2, blobs[r].y + blobs[r].height / 2); putText(images[i], txt.str().c_str(), origin, cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 0, 0), 1); } } std::ostringstream name1; name1 << "Original " << i + 1; cv::namedWindow(name1.str().c_str(), 1); cv::imshow(name1.str().c_str(), images[i]); } cv::waitKey(0); /// ========================================================================== /// STITCH IT TOGETHER ======================================================= if (p == 0) { /// First write everything to files /// Create file fp = fopen(filename, "w"); int last_image_count = 0, blob_counter = 0; int *last_temp, *last; last_temp = new int[blobs.size() * 4 + blob_count.size()]; for (size_t i = 0; i < blobs.size(); i++) { if (blob_count[i] > blob_counter) { blob_counter = blob_count[i]; } fprintf(fp, "%d %d %d %d %d %d\n", image_count[i], blob_count[i], blobs[i].x, blobs[i].y, blobs[i].height, blobs[i].width); /// Create array for last image if (image_count[i] == I - 1) { /// The array "last_temp" (becomes "last" in the following lines) is the /// information of the blobs of the last slice for the current processor /// It is what will be sent to the next processor for merging the blobs last_temp[last_image_count * 5] = blob_count[i]; last_temp[last_image_count * 5 + 1] = blobs[i].x; last_temp[last_image_count * 5 + 2] = blobs[i].y; last_temp[last_image_count * 5 + 3] = blobs[i].height; last_temp[last_image_count * 5 + 4] = blobs[i].width; last_image_count++; } } if (last_image_count == 0) { last = new int[1]; last[0] = -1; } else { last = new int[last_image_count * 5]; memcpy(last_temp, last, last_image_count * 5 * sizeof(int)); } // Close file fclose(fp); // Send last slide to next process if (P > 1) { MPI_Send(&blob_counter, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); /// Highest blob label MPI_Send(&last_image_count, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); /// Number of blobs found in the last slice MPI_Send(&last, last_image_count * 5, MPI_INT, 1, 0, MPI_COMM_WORLD); /// Last slice's blobs } } else { // Wait for signal from previous process int num_blobs = 0, *previous, previous_blob_counter = 0; MPI_Recv(&previous_blob_counter, 1, MPI_INT, p - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&num_blobs, 1, MPI_INT, p - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); previous = new int[num_blobs * 5]; MPI_Recv(previous, num_blobs * 5, MPI_INT, p - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); std::vector<int> old_blob_count; for (size_t blob = 0; blob < blob_count.size(); blob++) { blob_count[blob] += 100; old_blob_count.push_back(blob_count[blob]); } if (num_blobs != 0) { std::vector<cv::Rect> prev_blobs; std::vector<int> prev_blob_count; for (int i = 0; i < num_blobs; i++) { cv::Rect temp; prev_blob_count.push_back(previous[i * 5]); temp.x = previous[i * 5 + 1]; temp.y = previous[i * 5 + 2]; temp.height = previous[i * 5 + 3]; temp.width = previous[i * 5 + 4]; prev_blobs.push_back(temp); } for (int blob = 0; blob < num_blobs; blob++) { for (size_t i = 0; i < image_count.size(); i++) { if (image_count[i] == 0) { /// The first slice needs to be compared with the previous one cv::Rect intersection = blobs[i] & prev_blobs[blob]; if (intersection.height != 0 && intersection.width != 0) { blob_count[i] = prev_blob_count[blob]; } } } } /// At this point the first slice has the same labels as the previous one /// We need to replace the blob labels for (size_t i = 0; i < blob_count.size(); i++) { if (image_count[i] == 0) { int new_label = blob_count[i]; int old_label = old_blob_count[i]; for (size_t j = 0; j < blob_count.size(); j++) { if (blob_count[j] == old_label) { blob_count[j] = new_label; } } } } } /// Change all labels to be the increment of the previous slide for (size_t i = 0; i < blob_count.size(); i++) { if (blob_count[i] > previous_blob_counter) { int old_label = blob_count[i]; for (size_t j = i; j < blob_count.size(); j++) { if (blob_count[j] == old_label) { previous_blob_counter++; blob_count[j] = previous_blob_counter; } } } } /// Open file to append fp = fopen(filename, "a"); int last_image_count = 0; int *last_temp, *last; last_temp = new int[blobs.size() * 4 + blob_count.size()]; for (size_t i = 0; i < blobs.size(); i++) { /// Create array for last image if (image_count[i] == I - 1) { last_temp[last_image_count * 5] = blob_count[i]; last_temp[last_image_count * 5 + 1] = blobs[i].x; last_temp[last_image_count * 5 + 2] = blobs[i].y; last_temp[last_image_count * 5 + 3] = blobs[i].height; last_temp[last_image_count * 5 + 4] = blobs[i].width; last_image_count++; } /// Fix image counter int im_count; im_count = p * ((int) (N / P)) + std::min(P, (N % P) + image_count[i]); fprintf(fp, "%d %d %d %d %d %d\n", im_count, blob_count[i], blobs[i].x, blobs[i].y, blobs[i].height, blobs[i].width); } if (last_image_count == 0) { last = new int[1]; last[0] = -1; } else { last = new int[last_image_count * 5]; memcpy(last_temp, last, last_image_count * 5 * sizeof(int)); } // Close file fclose(fp); // Send signal to next process if (p != P - 1) { MPI_Send(&previous_blob_counter, 1, MPI_INT, p + 1, 0, MPI_COMM_WORLD); MPI_Send(&last_image_count, 1, MPI_INT, p + 1, 0, MPI_COMM_WORLD); MPI_Send(&last, last_image_count * 5, MPI_INT, p + 1, 0, MPI_COMM_WORLD); } } end_time = MPI_Wtime(); if (p == 0) { printf ("%e", end_time - start_time); } /* That's it */ MPI_Finalize(); exit(0); return 0; }
int main(int argc, char* argv[]) { // cv::CommandLineParserに渡すオプションの書式 // 以下の順に記述する。 // 省略名 (-hの形式) | 完全名 (--helpの形式) | デフォルト値 (省略可能) | 説明 const char* option_keys = "{h| help| false| show help message}" "{o| out| out.png| output file name}" "{s| show| false| show output in window}" "{l| imagelist| | imagelist filename}" "{i| images| | image filenames separated with comma}"; cv::CommandLineParser parser(argc, argv, option_keys); auto options = get_options(parser); if(options.show_help) { std::cout << "This program is sample code of cv::Stitcher." << std::endl; // cv::CommandLineParser::printParams() はオプションの概説を std::cout に出力する。 parser.printParams(); return 0; } // imagelist に記述されたファイル名を取得 auto imagelist = read_imagelist(options.imagelist_filename); // コマンドライン引数で渡されたファイル名と結合 imagelist.insert(imagelist.end(), options.filenames.begin(), options.filenames.end()); // 全画像ファイルを読み込み auto images = read_images(imagelist); if( images.empty() ) { std::cout << "no image read" << std::endl; return -1; } if( images.size() != imagelist.size() ) { std::cout << "some images are not able to be loaded" << std::endl; } cv::Mat panorama; auto stitcher = cv::Stitcher::createDefault(false); // cv::Stitcher::stitch() のみでスティッチングを行える。 auto status = stitcher.stitch(images, panorama); if( status != cv::Stitcher::OK ) { std::cout << "stitching failed" << std::endl; return -1; } if(options.show_result) { cv::namedWindow("image", CV_WINDOW_AUTOSIZE | CV_WINDOW_FREERATIO); cv::imshow("image", panorama); cv::waitKey(); } cv::imwrite(options.output_filename, panorama); return 0; }
int main(int argc, char *argv[]) { /// Read Images std::vector<cv::Mat> images = read_images(); for (size_t i = 1; i < images.size(); i++) { if (images[0].rows != images[i].rows || images[0].cols != images[i].cols) { std::cout << "ERROR: Images need to be of the same size\n"; return -1; } } /// Reshape Image int number_of_pixels = 0; for (int i = 0; i < SLICES; i++) { number_of_pixels += images[i].rows * images[i].cols; } cv::Mat pixel_values; for (int i = 0; i < SLICES; i++) { cv::Mat temp; images[i].reshape(1, images[i].rows * images[i].cols).copyTo(temp); pixel_values.push_back(temp); } pixel_values.convertTo(pixel_values, CV_32F); /// Do k-means cv::Mat bestLabels; cv::kmeans(pixel_values, K, bestLabels, cv::TermCriteria(), 10, cv::KMEANS_RANDOM_CENTERS); std::vector<cv::Mat> clustered_images; /// bestLabels, contains the number of the cluster to which each pixel belongs int so_far = 0; for (int i = 0; i < SLICES; i++) { cv::Mat temp; bestLabels.rowRange(so_far, so_far + images[i].rows * images[i].cols) .copyTo(temp); so_far += images[i].rows * images[i].cols; // cv::Mat new_temp; temp = temp.reshape(1, images[i].rows); clustered_images.push_back(temp); } std::vector<cv::Rect> blobs; std::vector<int> blob_count; std::vector<int> image_count; three_d_connected_components(clustered_images, blobs, image_count, blob_count); for (size_t i = 0; i < blob_count.size(); i++) { blob_count[i] -= K; } /// Show images for (int i = 0; i < SLICES; i++) { /// Draw rectangles on image for (size_t r = 0; r < image_count.size(); r++) { if (image_count[r] == i) { rectangle(images[i], blobs[r], cv::Scalar(0, 0, 0), 1); std::ostringstream txt; txt << blob_count[r]; cv::Point origin(blobs[r].x + blobs[r].width / 2, blobs[r].y + blobs[r].height / 2); putText(images[i], txt.str().c_str(), origin, cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 0, 0), 1); } } std::ostringstream name1; name1 << "Original " << i + 1; cv::namedWindow(name1.str().c_str(), 1); cv::imshow(name1.str().c_str(), images[i]); } cv::waitKey(0); return 0; }