You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
3.7 KiB

  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cmath>
  4. #include <mpi.h>
  5. #include "Ttiming.h"
  6. #include <opencv2/opencv.hpp>
  7. using namespace std;
  8. using namespace cv;
  9. #define RX 5
  10. #define RY 5
  11. int main(int argc, char *argv[])
  12. {
  13. int i,j,k,l,m,n;
  14. TTiming tt;
  15. int sumka_r, sumka_g, sumka_b;
  16. int suma_wag = 0;
  17. Mat img_out;
  18. int porcja_new=0;
  19. Mat img;
  20. Mat img_part_out;
  21. int ratio[RX][RY] =
  22. {
  23. {1, 4, 7, 4, 1},
  24. {4, 16, 26, 16, 4},
  25. {7, 26, 41, 26, 7},
  26. {4, 16, 26, 16, 4},
  27. {1, 4, 7, 4, 1}
  28. };
  29. if (argc < 3)
  30. {
  31. cerr << "Usage: " << argv[0] << " <input_image> <output_image>" << endl;
  32. exit(1);
  33. }
  34. img = cv::imread(argv[1]);
  35. if(!img.data )
  36. {
  37. cerr << "File " << argv[1] << " does not exist" << endl;
  38. exit(1);
  39. }
  40. for (i=0; i<RX; ++i)
  41. for (j=0; j<RY; ++j)
  42. suma_wag += ratio[i][j];
  43. MPI::Init(argc, argv);
  44. int taskid = MPI::COMM_WORLD.Get_rank();
  45. int ntasks = MPI::COMM_WORLD.Get_size();
  46. // porcja - ile wektorów dostaje jeden proces do liczenia
  47. // jeżeli liczba procesów większa od wektorów - każdy proces dostaje po jednym, niektóre wcale
  48. int porcja = (img.rows>=ntasks) ? (int)round(img.rows*1.0/ntasks) : 1;
  49. //porcja *= img.cols; //porcję mnożymy przez ilość elementów w jednym wektorze
  50. porcja_new = porcja;
  51. if (taskid == 0)
  52. img_out.create(img.rows, img.cols, img.type());
  53. int *chunk_sizes = new int[ntasks];
  54. int *chunk_order = new int[ntasks];
  55. //liczę tablicę z danymi - o tym ile dany chunk ma rozmiaru oraz offset w tablicy od pierwszego procesu
  56. for (i=0; i<ntasks; ++i)
  57. {
  58. chunk_order[i] = (i == 0) ? 0 : chunk_order[i-1] + chunk_sizes[i-1];
  59. chunk_sizes[i] = porcja*img.cols*3;
  60. if (i == ntasks-1)
  61. chunk_sizes[i] = (img.rows - porcja*(ntasks-1))*img.cols*3;
  62. }
  63. MPI::COMM_WORLD.Barrier();
  64. //
  65. // część licząca ---------------------------------------------------------------------------------
  66. //
  67. MPI::COMM_WORLD.Barrier();
  68. if (taskid == 0)
  69. tt.Begin();
  70. int start_pos = taskid*porcja;
  71. int stop_pos = (taskid+1)*porcja;
  72. if (taskid == ntasks -1) //przelicz porcję dla ostatniego procesu (w przypadku dzielenia z resztą)
  73. {
  74. porcja_new = img.rows - porcja*(ntasks-1);
  75. // myk jest taki, że muszę podać jakąś niezerową porcję do gathera,
  76. // mimo, że proces nie ma żadnych (sensownych) danych do przetworzenia
  77. if (porcja_new > 0)
  78. {
  79. stop_pos = img.rows;
  80. porcja = porcja_new;
  81. }
  82. }
  83. img_part_out.create(porcja, img.cols, img.type());
  84. int p=0, q=0;
  85. for (i=start_pos; i<stop_pos; ++i)
  86. {
  87. q = 0;
  88. for (j=0; j<img.cols; ++j)
  89. {
  90. if (i<2 || i>img.rows-3 || j<2 || j>img.cols-3)
  91. {
  92. img_part_out.at<Vec3b>(p, q)[0] = img.at<Vec3b>(i, j)[0];
  93. img_part_out.at<Vec3b>(p, q)[1] = img.at<Vec3b>(i, j)[1];
  94. img_part_out.at<Vec3b>(p, q)[2] = img.at<Vec3b>(i, j)[2];
  95. }
  96. else
  97. {
  98. sumka_r = 0;
  99. sumka_g = 0;
  100. sumka_b = 0;
  101. m=i-2;
  102. for (k=0; k<RX; ++k,++m)
  103. {
  104. n=j-2;
  105. for (l=0; l<RY; ++l,++n)
  106. {
  107. sumka_b += ratio[k][l] * img.at<Vec3b>(m, n)[0];
  108. sumka_g += ratio[k][l] * img.at<Vec3b>(m, n)[1];
  109. sumka_r += ratio[k][l] * img.at<Vec3b>(m, n)[2];
  110. }
  111. }
  112. img_part_out.at<Vec3b>(p, q).val[0] = sumka_b / suma_wag;
  113. img_part_out.at<Vec3b>(p, q).val[1] = sumka_g / suma_wag;
  114. img_part_out.at<Vec3b>(p, q).val[2] = sumka_r / suma_wag;
  115. }
  116. ++q;
  117. }
  118. ++p;
  119. }
  120. MPI::COMM_WORLD.Barrier();
  121. if (taskid == 0)
  122. {
  123. long elapsed = tt.End();
  124. cout << "Time: " << elapsed << " ms" << endl;
  125. }
  126. // zwróć wszystko do programu głównego
  127. MPI::COMM_WORLD.Gatherv(&img_part_out.data[0], porcja*img.cols*3, MPI::CHAR, &img_out.data[0], chunk_sizes, chunk_order, MPI::CHAR, 0);
  128. if (taskid == 0)
  129. imwrite(argv[2], img_out);
  130. MPI::Finalize();
  131. exit(0);
  132. }