Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ParalellProg_lab1.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <iostream>
- #include <cmath>
- #include <algorithm>
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2/opencv.hpp>
- #include <opencv2/imgproc/imgproc.hpp>
- #include <opencv2/objdetect/objdetect.hpp>
- #include <mpi.h>
- using namespace std;
- using namespace cv;
- #define ll long long
- const int radius = 1;
- const vector<vector<int>> sobel_x = { {-1 , 0 , 1} , {-2 , 0 , 2} , {-1 , 0 , 1} };
- const vector<vector<int>> sobel_y = { {-1 , -2 , -1} , {0 , 0 , 0} , {1 , 2 , 1} };
- int worldSize;
- int worldRank;
- char processorName[MPI_MAX_PROCESSOR_NAME];
- int nameLength;
- static volatile double ans = 0;
- static vector<string> q;
- int ** alloc_2d_int(int rows, int cols) {
- int * data = (int *)malloc(rows * cols * sizeof(int));
- int ** arr = (int **)malloc(rows * sizeof(int *));
- for (int i = 0; i < rows; ++i)
- arr[i] = &(data[cols * i]);
- return arr;
- }
- int main(int argc, char* argv[]) {
- int flag;
- MPI_Initialized(&flag);
- if (!flag)
- MPI_Init(&argc, &argv);
- MPI_Comm_size(MPI_COMM_WORLD, &worldSize);
- MPI_Comm_rank(MPI_COMM_WORLD, &worldRank);
- MPI_Status status;
- int ** gradX;
- int ** gradY;
- int fcnt;
- if (worldRank == 0) {
- freopen("files.txt", "r", stdin);
- string str;
- while (getline(cin, str))q.push_back(str);
- fcnt = q.size();
- for (int i = 1; i < worldSize; ++i)
- MPI_Send(&fcnt, 1, MPI_INT, i, 99, MPI_COMM_WORLD);
- }
- else {
- MPI_Recv(&fcnt, 1, MPI_INT, 0, 99, MPI_COMM_WORLD, &status);
- }
- Mat img;
- Mat img_gray, image_blur;
- ll before = clock();
- for (int img1 = 0; img1 < fcnt ; ++img1) {
- int n, m, start, rpp , first_row;
- int ** A;
- int last_row = 1;
- int fi, la;
- if (worldRank == 0) {//Big boss
- String path = q[img1];
- img = imread(path);
- GaussianBlur(img, image_blur, Size(5, 5), 3, 3);
- cvtColor(image_blur, img_gray, CV_RGB2GRAY);
- int cols = img_gray.cols;
- int rows = img_gray.rows;
- int rows_per_proc = rows / worldSize;
- Mat _src;
- copyMakeBorder(img_gray, _src, radius, radius, radius, radius, BORDER_REFLECT101);
- n = rows;
- m = cols;
- fi = 1;
- la = fi + rows_per_proc - 1;
- for (int i = 1; i < worldSize; ++i){
- MPI_Send(&fi, 1, MPI_INT, i, 100, MPI_COMM_WORLD);
- int ** tmp;
- tmp = alloc_2d_int(rows_per_proc + 2, cols);
- MPI_Send(&la, 1, MPI_INT, i, 101, MPI_COMM_WORLD);
- MPI_Send(&m, 1, MPI_INT, i, 102, MPI_COMM_WORLD);
- for (int x = fi - 1; x <= la + 1; ++x) {
- for (int y = 0; y < cols; ++y) {
- tmp[x - fi + 1][y] = _src.at<uchar>(x, y);
- }
- }
- fi = la + 1;
- la = fi + rows_per_proc - 1;
- MPI_Send(&(tmp[0][0]), (rows_per_proc + 2) * cols, MPI_INT, i, 103, MPI_COMM_WORLD);
- }
- la = n - 1;
- A = alloc_2d_int((la - fi + 3), m);
- for (int x = fi - 1; x <= la; ++x) {
- for (int y = 0; y < cols; ++y) {
- A[x - fi + 1][y] = _src.at<uchar>(x, y);
- }
- }
- }
- else {
- MPI_Recv(&fi, 1, MPI_INT, 0, 100, MPI_COMM_WORLD, &status);
- MPI_Recv(&la, 1, MPI_INT, 0, 101, MPI_COMM_WORLD, &status);
- MPI_Recv(&m, 1, MPI_INT, 0, 102, MPI_COMM_WORLD, &status);
- A = alloc_2d_int((la - fi + 3), m);
- MPI_Recv(&(A[0][0]), (la - fi + 3) * m, MPI_INT, 0, 103, MPI_COMM_WORLD, &status);
- }
- gradX = alloc_2d_int((la - fi + 3), m);
- gradY = alloc_2d_int((la - fi + 3), m);
- for (int r = radius; r < (la - fi + 3) - radius; ++r) {
- for (int c = radius ; c < m - radius; ++c) {
- int sx = 0, sy = 0;
- for (int i = -radius; i <= radius; ++i) {
- for (int j = -radius; j <= radius; ++j) {
- sx += A[r + i][c + j] * sobel_x[i + radius][j + radius];
- sy += A[r + i][c + j] * sobel_y[i + radius][j + radius];
- }
- }
- sx /= 30;
- sy /= 30;
- gradX[r - radius][c - radius] = sx;
- gradY[r - radius][c - radius] = sy;
- }
- }
- free(A[0]); free(A);
- if (worldRank == 0) {
- int ** finalGradX;
- int ** finalGradY;
- int ** tmpX;
- int ** tmpY;
- finalGradX = alloc_2d_int(n + 10, m + 10);
- finalGradY = alloc_2d_int(n + 10, m + 10);
- for (int i = 1; i < worldSize; ++i) {
- int cfi, cla;
- MPI_Recv(&cfi, 1, MPI_INT, i, 105, MPI_COMM_WORLD, &status);
- MPI_Recv(&cla, 1, MPI_INT, i, 106, MPI_COMM_WORLD, &status);
- tmpX = alloc_2d_int((cla - cfi + 3), m);
- tmpY = alloc_2d_int((cla - cfi + 3), m);
- MPI_Recv(&(tmpX[0][0]), (cla - cfi + 3) * m, MPI_INT, i, 107, MPI_COMM_WORLD, &status);
- MPI_Recv(&(tmpY[0][0]), (cla - cfi + 3) * m, MPI_INT, i, 108, MPI_COMM_WORLD, &status);
- for (int x = cfi; x <= cla; ++x) {
- for (int y = 0; y < m; ++y) {
- finalGradX[x][y] = tmpX[x - cfi][y];
- finalGradY[x][y] = tmpY[x - cfi][y];
- }
- }
- free(tmpX[0]); free(tmpY[0]);
- free(tmpX); free(tmpY);
- }
- for (int x = 0; x < m; ++x)gradX[0][x] = gradY[0][x] = 0;
- for (int x = fi; x <= la; ++x) {
- for (int y = 0; y < m; ++y) {
- finalGradX[x][y] = gradX[x - fi][y];
- finalGradY[x][y] = gradY[x - fi][y];
- }
- }
- free(gradX[0]); free(gradY[0]);
- free(gradX); free(gradY);
- Mat gradient_x = img_gray.clone();
- Mat gradient_y = img_gray.clone();
- Mat gradient_f = img_gray.clone();
- for (int i = 0; i < gradient_x.rows; ++i)
- for (int j = 0; j < gradient_x.cols; ++j) {
- gradient_x.at<uchar>(i, j) = finalGradX[i][j];
- gradient_y.at<uchar>(i, j) = finalGradY[i][j];
- }
- free(finalGradX[0]); free(finalGradY[0]);
- free(finalGradX); free(finalGradY);
- Mat absGrad_x, absGrad_y;
- convertScaleAbs(gradient_x, absGrad_x);
- convertScaleAbs(gradient_y, absGrad_y);
- for (int i = 0; i < gradient_f.rows; i++) {
- for (int j = 0; j < gradient_f.cols; j++) {
- gradient_f.at<uchar>(i, j) = sqrt(pow(gradient_x.at<uchar>(i, j), 2) + pow(gradient_y.at<uchar>(i, j), 2));
- gradient_f.at<uchar>(i, j) = gradient_f.at<uchar>(i, j) >= 240 ? 100 : 0;
- }
- }
- imwrite(q[img1] + "output.jpg", gradient_f);
- }
- else {
- MPI_Send(&fi, 1, MPI_INT, 0, 105, MPI_COMM_WORLD);
- MPI_Send(&la, 1, MPI_INT, 0, 106, MPI_COMM_WORLD);
- MPI_Send(&(gradX[0][0]), (la - fi + 3) * m, MPI_INT, 0, 107, MPI_COMM_WORLD);
- MPI_Send(&(gradY[0][0]), (la - fi + 3) * m, MPI_INT, 0, 108, MPI_COMM_WORLD);
- free(gradX[0]); free(gradY[0]);
- free(gradX); free(gradY);
- }
- }
- if (worldRank == 0) {
- ll after = clock();
- cout << "Total time: " << (double)(after - before) / CLOCKS_PER_SEC << " sec" << endl;
- cout << "Average time: " << (double)((after - before) / CLOCKS_PER_SEC) / q.size() << " sec" << endl;
- }
- MPI_Finalize();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement