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.

155 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. MPI::Finalize();
  39. exit(1);
  40. }
  41. for (i=0; i<RX; ++i)
  42. for (j=0; j<RY; ++j)
  43. suma_wag += ratio[i][j];
  44. MPI::Init(argc, argv);
  45. int taskid = MPI::COMM_WORLD.Get_rank();
  46. int ntasks = MPI::COMM_WORLD.Get_size();
  47. // porcja - ile wektorów dostaje jeden proces do liczenia
  48. // jeżeli liczba procesów większa od wektorów - każdy proces dostaje po jednym, niektóre wcale
  49. int porcja = (img.rows>=ntasks) ? (int)round(img.rows*1.0/ntasks) : 1;
  50. //porcja *= img.cols; //porcję mnożymy przez ilość elementów w jednym wektorze
  51. porcja_new = porcja;
  52. if (taskid == 0)
  53. img_out.create(img.rows, img.cols, img.type());
  54. int *chunk_sizes = new int[ntasks];
  55. int *chunk_order = new int[ntasks];
  56. //liczę tablicę z danymi - o tym ile dany chunk ma rozmiaru oraz offset w tablicy od pierwszego procesu
  57. for (i=0; i<ntasks; ++i)
  58. {
  59. chunk_order[i] = (i == 0) ? 0 : chunk_order[i-1] + chunk_sizes[i-1];
  60. chunk_sizes[i] = porcja*img.cols*3;
  61. if (i == ntasks-1)
  62. chunk_sizes[i] = (img.rows - porcja*(ntasks-1))*img.cols*3;
  63. }
  64. MPI::COMM_WORLD.Barrier();
  65. //
  66. // część licząca ---------------------------------------------------------------------------------
  67. //
  68. MPI::COMM_WORLD.Barrier();
  69. if (taskid == 0)
  70. tt.Begin();
  71. int start_pos = taskid*porcja;
  72. int stop_pos = (taskid+1)*porcja;
  73. if (taskid == ntasks -1) //przelicz porcję dla ostatniego procesu (w przypadku dzielenia z resztą)
  74. {
  75. porcja_new = img.rows - porcja*(ntasks-1);
  76. // myk jest taki, że muszę podać jakąś niezerową porcję do gathera,
  77. // mimo, że proces nie ma żadnych (sensownych) danych do przetworzenia
  78. if (porcja_new > 0)
  79. {
  80. stop_pos = img.rows;
  81. porcja = porcja_new;
  82. }
  83. }
  84. img_part_out.create(porcja, img.cols, img.type());
  85. int p=0, q=0;
  86. for (i=start_pos; i<stop_pos; ++i)
  87. {
  88. q = 0;
  89. for (j=0; j<img.cols; ++j)
  90. {
  91. if (i<2 || i>img.rows-3 || j<2 || j>img.cols-3)
  92. {
  93. img_part_out.at<Vec3b>(p, q)[0] = img.at<Vec3b>(i, j)[0];
  94. img_part_out.at<Vec3b>(p, q)[1] = img.at<Vec3b>(i, j)[1];
  95. img_part_out.at<Vec3b>(p, q)[2] = img.at<Vec3b>(i, j)[2];
  96. }
  97. else
  98. {
  99. sumka_r = 0;
  100. sumka_g = 0;
  101. sumka_b = 0;
  102. m=i-2;
  103. for (k=0; k<RX; ++k,++m)
  104. {
  105. n=j-2;
  106. for (l=0; l<RY; ++l,++n)
  107. {
  108. sumka_b += ratio[k][l] * img.at<Vec3b>(m, n)[0];
  109. sumka_g += ratio[k][l] * img.at<Vec3b>(m, n)[1];
  110. sumka_r += ratio[k][l] * img.at<Vec3b>(m, n)[2];
  111. }
  112. }
  113. img_part_out.at<Vec3b>(p, q).val[0] = sumka_b / suma_wag;
  114. img_part_out.at<Vec3b>(p, q).val[1] = sumka_g / suma_wag;
  115. img_part_out.at<Vec3b>(p, q).val[2] = sumka_r / suma_wag;
  116. }
  117. ++q;
  118. }
  119. ++p;
  120. }
  121. MPI::COMM_WORLD.Barrier();
  122. if (taskid == 0)
  123. {
  124. long elapsed = tt.End();
  125. cout << "Time: " << elapsed << " ms" << endl;
  126. }
  127. // zwróć wszystko do programu głównego
  128. 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);
  129. if (taskid == 0)
  130. imwrite(argv[2], img_out);
  131. MPI::Finalize();
  132. exit(0);
  133. }