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

#include <iostream>
#include <cstdlib>
#include <cmath>
#include <mpi.h>
#include "Ttiming.h"
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define RX 5
#define RY 5
int main(int argc, char *argv[])
{
int i,j,k,l,m,n;
TTiming tt;
int sumka_r, sumka_g, sumka_b;
int suma_wag = 0;
Mat img_out;
int porcja_new=0;
Mat img;
Mat img_part_out;
int ratio[RX][RY] =
{
{1, 4, 7, 4, 1},
{4, 16, 26, 16, 4},
{7, 26, 41, 26, 7},
{4, 16, 26, 16, 4},
{1, 4, 7, 4, 1}
};
if (argc < 3)
{
cerr << "Usage: " << argv[0] << " <input_image> <output_image>" << endl;
exit(1);
}
img = cv::imread(argv[1]);
if(!img.data )
{
cerr << "File " << argv[1] << " does not exist" << endl;
exit(1);
}
for (i=0; i<RX; ++i)
for (j=0; j<RY; ++j)
suma_wag += ratio[i][j];
MPI::Init(argc, argv);
int taskid = MPI::COMM_WORLD.Get_rank();
int ntasks = MPI::COMM_WORLD.Get_size();
// porcja - ile wektorów dostaje jeden proces do liczenia
// jeżeli liczba procesów większa od wektorów - każdy proces dostaje po jednym, niektóre wcale
int porcja = (img.rows>=ntasks) ? (int)round(img.rows*1.0/ntasks) : 1;
//porcja *= img.cols; //porcję mnożymy przez ilość elementów w jednym wektorze
porcja_new = porcja;
if (taskid == 0)
img_out.create(img.rows, img.cols, img.type());
int *chunk_sizes = new int[ntasks];
int *chunk_order = new int[ntasks];
//liczę tablicę z danymi - o tym ile dany chunk ma rozmiaru oraz offset w tablicy od pierwszego procesu
for (i=0; i<ntasks; ++i)
{
chunk_order[i] = (i == 0) ? 0 : chunk_order[i-1] + chunk_sizes[i-1];
chunk_sizes[i] = porcja*img.cols*3;
if (i == ntasks-1)
chunk_sizes[i] = (img.rows - porcja*(ntasks-1))*img.cols*3;
}
MPI::COMM_WORLD.Barrier();
//
// część licząca ---------------------------------------------------------------------------------
//
MPI::COMM_WORLD.Barrier();
if (taskid == 0)
tt.Begin();
int start_pos = taskid*porcja;
int stop_pos = (taskid+1)*porcja;
if (taskid == ntasks -1) //przelicz porcję dla ostatniego procesu (w przypadku dzielenia z resztą)
{
porcja_new = img.rows - porcja*(ntasks-1);
// myk jest taki, że muszę podać jakąś niezerową porcję do gathera,
// mimo, że proces nie ma żadnych (sensownych) danych do przetworzenia
if (porcja_new > 0)
{
stop_pos = img.rows;
porcja = porcja_new;
}
}
img_part_out.create(porcja, img.cols, img.type());
int p=0, q=0;
for (i=start_pos; i<stop_pos; ++i)
{
q = 0;
for (j=0; j<img.cols; ++j)
{
if (i<2 || i>img.rows-3 || j<2 || j>img.cols-3)
{
img_part_out.at<Vec3b>(p, q)[0] = img.at<Vec3b>(i, j)[0];
img_part_out.at<Vec3b>(p, q)[1] = img.at<Vec3b>(i, j)[1];
img_part_out.at<Vec3b>(p, q)[2] = img.at<Vec3b>(i, j)[2];
}
else
{
sumka_r = 0;
sumka_g = 0;
sumka_b = 0;
m=i-2;
for (k=0; k<RX; ++k,++m)
{
n=j-2;
for (l=0; l<RY; ++l,++n)
{
sumka_b += ratio[k][l] * img.at<Vec3b>(m, n)[0];
sumka_g += ratio[k][l] * img.at<Vec3b>(m, n)[1];
sumka_r += ratio[k][l] * img.at<Vec3b>(m, n)[2];
}
}
img_part_out.at<Vec3b>(p, q).val[0] = sumka_b / suma_wag;
img_part_out.at<Vec3b>(p, q).val[1] = sumka_g / suma_wag;
img_part_out.at<Vec3b>(p, q).val[2] = sumka_r / suma_wag;
}
++q;
}
++p;
}
MPI::COMM_WORLD.Barrier();
if (taskid == 0)
{
long elapsed = tt.End();
cout << "Time: " << elapsed << " ms" << endl;
}
// zwróć wszystko do programu głównego
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);
if (taskid == 0)
imwrite(argv[2], img_out);
MPI::Finalize();
exit(0);
}