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.

149 lines
3.6 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 buff_max=0,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. // dla kompatybilności liczę jeszcze rozmiar bufora odbioru,
  53. // np. jeżeli chunki będą jednolitego rozmiaru, a ostatni będzie większy
  54. // to bufor odbioru musi być zwiększony (żeby go nie ucinało)
  55. buff_max = img.rows - porcja*(ntasks-1);
  56. if (porcja > buff_max)
  57. buff_max = porcja; // na wypadek, jeżeli jednak ostatni kawałek będzie mniejszy
  58. if (taskid == 0)
  59. img_out.create(/*buff_max*ntasks*/img.rows, img.cols, img.type());
  60. MPI::COMM_WORLD.Barrier();
  61. //
  62. // część licząca ---------------------------------------------------------------------------------
  63. //
  64. MPI::COMM_WORLD.Barrier();
  65. if (taskid == 0)
  66. tt.Begin();
  67. int start_pos = taskid*porcja;
  68. int stop_pos = (taskid+1)*porcja;
  69. if (taskid == ntasks -1) //przelicz porcję dla ostatniego procesu (w przypadku dzielenia z resztą)
  70. {
  71. porcja_new = img.rows - porcja*(ntasks-1);
  72. // myk jest taki, że muszę podać jakąś niezerową porcję do gathera,
  73. // mimo, że proces nie ma żadnych (sensownych) danych do przetworzenia
  74. if (porcja_new > 0)
  75. {
  76. stop_pos = img.rows;
  77. porcja = porcja_new;
  78. }
  79. }
  80. img_part_out.create(porcja, img.cols, img.type());
  81. int p=0, q=0;
  82. for (i=start_pos; i<stop_pos; ++i)
  83. {
  84. q = 0;
  85. for (j=0; j<img.cols; ++j)
  86. {
  87. if (i<2 || i>img.rows-3 || j<2 || j>img.cols-3)
  88. {
  89. img_part_out.at<Vec3b>(p, q)[0] = img.at<Vec3b>(i, j)[0];
  90. img_part_out.at<Vec3b>(p, q)[1] = img.at<Vec3b>(i, j)[1];
  91. img_part_out.at<Vec3b>(p, q)[2] = img.at<Vec3b>(i, j)[2];
  92. }
  93. else
  94. {
  95. sumka_r = 0;
  96. sumka_g = 0;
  97. sumka_b = 0;
  98. m=i-2;
  99. for (k=0; k<RX; ++k,++m)
  100. {
  101. n=j-2;
  102. for (l=0; l<RY; ++l,++n)
  103. {
  104. sumka_b += ratio[k][l] * img.at<Vec3b>(m, n)[0];
  105. sumka_g += ratio[k][l] * img.at<Vec3b>(m, n)[1];
  106. sumka_r += ratio[k][l] * img.at<Vec3b>(m, n)[2];
  107. }
  108. }
  109. img_part_out.at<Vec3b>(p, q).val[0] = sumka_b / suma_wag;
  110. img_part_out.at<Vec3b>(p, q).val[1] = sumka_g / suma_wag;
  111. img_part_out.at<Vec3b>(p, q).val[2] = sumka_r / suma_wag;
  112. }
  113. ++q;
  114. }
  115. ++p;
  116. }
  117. MPI::COMM_WORLD.Barrier();
  118. if (taskid == 0)
  119. {
  120. long elapsed = tt.End();
  121. cout << "Time: " << elapsed << " ms" << endl;
  122. }
  123. // zwróć wszystko do programu głównego
  124. MPI::COMM_WORLD.Gather(&img_part_out.data[0], porcja*img.cols*3, MPI::CHAR, &img_out.data[0], porcja*img.cols*3, MPI::CHAR, 0);
  125. if (taskid == 0)
  126. imwrite(argv[2], img_out);
  127. MPI::Finalize();
  128. exit(0);
  129. }