|
Laboratoriya ishi №2 Openmp parallellashtirish kutubxonasi bilan tanishish va uning yordamida parallel dasturlar tuzush
|
bet | 2/2 | Sana | 26.01.2024 | Hajmi | 0,51 Mb. | | #146544 |
Bog'liq Amaliy ish 2 3.Topshiriqlar bajarilishi
Bir o’lchovli signallar ustida qayta ishlash amallarini omp kutubxonasi imkoniyatlaridan foydalanib amalga oshirish.
Signallarni qayta ishlash masalalari:
a) Signallarni oynalardan o’tkazish (Hemming,Henning va boshqalar);
#include
#include
#include
#include
// Hamming oynasini yaratish funksiyasi
std::vector createHammingWindow(int size) {
std::vector window(size);
#pragma omp parallel for
for (int i = 0; i < size; ++i) {
window[i] = 0.54 - 0.46 * cos(2 * M_PI * i / (size - 1));
}
return window;
}
// Hanning oynasini yaratish funksiyasi
std::vector createHanningWindow(int size) {
std::vector window(size);
#pragma omp parallel for
for (int i = 0; i < size; ++i) {
window[i] = 0.5 * (1 - cos(2 * M_PI * i / (size - 1)));
}
return window;
}
// Signalni oynadan o'tkazish funksiyasi
std::vector applyWindow(const std::vector& signal, const std::vector& window) {
int size = signal.size();
std::vector windowedSignal(size);
#pragma omp parallel for
for (int i = 0; i < size; ++i) {
windowedSignal[i] = signal[i] * window[i];
}
return windowedSignal;
}
int main() {
int windowSize = 10; // Oyna hajmini tanlang
std::vector signal(windowSize, 1); // Misol uchun bitta qiymatli signal
std::vector hammingWindow = createHammingWindow(windowSize);
std::vector hanningWindow = createHanningWindow(windowSize);
std::vector windowedSignalHamming = applyWindow(signal, hammingWindow);
std::vector windowedSignalHanning = applyWindow(signal, hanningWindow);
// Natijalarni chop etish
for (double value : windowedSignalHamming) {
std::cout << "Hamming: " << value << std::endl;
}
for (double value : windowedSignalHanning) {
std::cout << "Hanning: " << value << std::endl;
}
return 0;
}
Bu kodda, #pragma omp parallel for direktivasi OpenMP tomonidan taqdim etilgan parallel for tsiklini belgilaydi. Bu orqali, oyna funksiyasini yaratish va signalni oynadan o'tkazish jarayonlari bir nechta ishchi oqimlarda parallel ravishda amalga oshiriladi, bu esa hisob-kitob samaradorligini oshiradi.
b) Spektral almashtishlarni amalga oshirish (Diskret kosinus almashtirish, Adamar, Xaara, Dobishe, Fur’ye almashtirish);
#include
#include
#include
#include
#include
typedef std::complex Complex;
typedef std::vector ComplexVector;
// Bit-reversal permutation
void bitReverse(ComplexVector& x) {
const size_t N = x.size();
size_t j = 0;
for (size_t i = 0; i < N; ++i) {
if (i < j) {
std::swap(x[i], x[j]);
}
size_t m = N / 2;
while (m >= 2 && j >= m) {
j -= m;
m /= 2;
}
j += m;
}
}
// Fast Fourier Transform (FFT)
void FFT(ComplexVector& x) {
const size_t N = x.size();
bitReverse(x);
#pragma omp parallel
{
#pragma omp single
{
for (size_t s = 1; s <= log2(N); ++s) {
const size_t m = 1 << s;
const Complex wm = exp(-Complex(0, 2.0 * M_PI / m));
#pragma omp for nowait
for (size_t k = 0; k < N; k += m) {
Complex w = 1.0;
for (size_t j = 0; j < m / 2; ++j) {
Complex t = w * x[k + j + m / 2];
Complex u = x[k + j];
x[k + j] = u + t;
x[k + j + m / 2] = u - t;
w *= wm;
}
}
}
}
}
}
int main() {
ComplexVector data = {1, 1, 1, 1, 0, 0, 0, 0}; // Misol uchun signal
FFT(data);
// FFT natijasini chop etish
for (auto val : data) {
std::cout << val << "\n";
}
return 0;
}
Ushbu kod FFT algoritmining parallel versiyasini ko'rsatadi. #pragma omp parallel va #pragma omp for nowait direktivalari yordamida tsikllar OpenMP tomonidan parallel ravishda bajariladi. FFT algoritmini tushunish va uning parallel versiyasini to'g'ri amalga oshirish ancha murakkab bo'lishi mumkin, shuning uchun bu kodni tushunish va ishlatishda ehtiyot bo'lish tavsiya etiladi.
c) Signallarni filetrlash;
#include
#include
#include
// Ko'p o'zgaruvchili o'rtacha filtri
void movingAverageFilter(const std::vector& input, std::vector& output, int windowSize) {
int halfWindow = windowSize / 2;
int n = input.size();
#pragma omp parallel for
for (int i = halfWindow; i < n - halfWindow; ++i) {
double sum = 0.0;
for (int j = i - halfWindow; j <= i + halfWindow; ++j) {
sum += input[j];
}
output[i] = sum / windowSize;
}
}
int main() {
std::vector signal = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // Misol uchun signal
int windowSize = 3; // Oyna hajmi
std::vector filteredSignal(signal.size(), 0);
movingAverageFilter(signal, filteredSignal, windowSize);
// Natijani chop etish
for (int i = 0; i < filteredSignal.size(); ++i) {
std::cout << filteredSignal[i] << " ";
}
std::cout << std::endl;
return 0;
}
Bu kodda, #pragma omp parallel for direktivasi yordamida movingAverageFilter funksiyasining for tsikli OpenMP tomonidan parallel ravishda bajariladi. Bu kod signalning har bir nuqtasi uchun o'rtacha qiymatni hisoblaydi va natijani filteredSignal vektorida saqlaydi.
d) Signallarni spektral sohada siqish.
#include
#include
#include
#include
#include
typedef std::complex Complex;
typedef std::vector ComplexVector;
// Bit-reversal permutation
void bitReverse(ComplexVector& x) {
const size_t N = x.size();
size_t j = 0;
for (size_t i = 0; i < N; ++i) {
if (i < j) {
std::swap(x[i], x[j]);
}
size_t m = N / 2;
while (m >= 2 && j >= m) {
j -= m;
m /= 2;
}
j += m;
}
}
// Fast Fourier Transform (FFT)
void FFT(ComplexVector& x) {
const size_t N = x.size();
bitReverse(x);
#pragma omp parallel
{
#pragma omp single
{
for (size_t s = 1; s <= log2(N); ++s) {
const size_t m = 1 << s;
const Complex wm = exp(-Complex(0, 2.0 * M_PI / m));
#pragma omp for nowait
for (size_t k = 0; k < N; k += m) {
Complex w = 1.0;
for (size_t j = 0; j < m / 2; ++j) {
Complex t = w * x[k + j + m / 2];
Complex u = x[k + j];
x[k + j] = u + t;
x[k + j + m / 2] = u - t;
w *= wm;
}
}
}
}
}
}
int main() {
ComplexVector data = {1, 1, 1, 1, 0, 0, 0, 0}; // Misol uchun signal
FFT(data);
// FFT natijasini chop etish
for (auto val : data) {
std::cout << val << "\n";
}
return 0;
}
Ushbu kod faqat FFT algoritmining parallel versiyasini ko'rsatadi. Signalni spektral sohada siqish uchun, FFT natijasini olib, ma'lum bir spektral komponentlarni olib tashlash kerak (masalan, past amplitudali komponentlarni siqish orqali), so'ngra invers FFT qo'llash orqali signalni qayta tiklash kerak. Bu jarayonlar murakkab matematik va signal ishlov berish bilimlarini talab etadi.
Ikki o’lchovli signallarni(tasvirlarni) qayta ishlash masalalarini omp kutubxonasi imkoniyatlaridan foydalanib amalga oshirish.
Tasvirlani qayta ishlash masalalari:
a) Tasvirlarni filterlash (box filter, medium filter, Gaus filter va boshqa);
#include
#include
#include
#include
typedef std::vector> Matrix;
// Gaussian Kernel yaratish
Matrix createGaussianKernel(int kernelSize, double sigma) {
Matrix kernel(kernelSize, std::vector(kernelSize));
double sum = 0.0; // normalizatsiya uchun yig'indi
int k = kernelSize / 2;
for (int i = -k; i <= k; i++) {
for (int j = -k; j <= k; j++) {
double sqDist = i * i + j * j;
kernel[i + k][j + k] = exp(-sqDist / (2 * sigma * sigma)) / (M_PI * 2 * sigma * sigma);
sum += kernel[i + k][j + k];
}
}
// Kernelni normalizatsiya qilish
for (int i = 0; i < kernelSize; i++) {
for (int j = 0; j < kernelSize; j++) {
kernel[i][j] /= sum;
}
}
return kernel;
}
// Tasvirga Gaussian filter qo'llash
void applyGaussianFilter(const Matrix& image, Matrix& result, const Matrix& kernel) {
int kernelSize = kernel.size();
int k = kernelSize / 2;
int height = image.size();
int width = image[0].size();
#pragma omp parallel for collapse(2)
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
double sum = 0.0;
for (int ki = -k; ki <= k; ki++) {
for (int kj = -k; kj <= k; kj++) {
int x = std::max(0, std::min(i + ki, height - 1));
int y = std::max(0, std::min(j + kj, width - 1));
sum += image[x][y] * kernel[ki + k][kj + k];
}
}
result[i][j] = sum;
}
}
}
int main() {
// Misol uchun 2D tasvir
Matrix image = {{...}}; // Tasvir ma'lumotlari bilan to'ldiring
int height = image.size();
int width = image[0].size();
Matrix result(height, std::vector(width));
int kernelSize = 5; // Kernel hajmi
double sigma = 1.0; // Gaussian sigma qiymati
Matrix kernel = createGaussianKernel(kernelSize, sigma);
applyGaussianFilter(image, result, kernel);
// Natijani chop etish
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
std::cout << result[i][j] << " ";
}
std::cout << std::endl;
}
return 0;
}
#pragma omp parallel for collapse(2) direktivasi ikkita ichma-ich for tsikllarini parallel ravishda bajarish uchun ishlatiladi. Shuningdek, Gaussian kernel yaratish jarayonida sigma parametri kernelning silliq darajasini belgilaydi. Kodning to'g'ri ishlashi uchun tasvirning o'lchamlariga mos keladigan ma'lumotlar bilan to'ldirilgan image matrisi kerak bo'ladi.
b) Tasvirlarni spektral almashtish (Diskret kosinus almashtirish, Adamar, Xaara, Dobishe, Fur’ye almashtirish);
#include
#include
#include
#include
#include
typedef std::complex Complex;
typedef std::vector> ComplexMatrix;
// Bit-reversal permutation for 1D FFT
void bitReverse(ComplexVector& x) {
// 1D bit-reversal permutation implementation
// ...
}
// 1D Fast Fourier Transform (FFT)
void FFT(ComplexVector& x) {
// 1D FFT implementation
// ...
}
// 2D Fast Fourier Transform
void FFT2D(ComplexMatrix& data) {
size_t rows = data.size();
size_t cols = data[0].size();
// Apply FFT to each row
#pragma omp parallel for
for (size_t i = 0; i < rows; ++i) {
FFT(data[i]);
}
// Apply FFT to each column
ComplexVector temp(rows);
#pragma omp parallel for private(temp)
for (size_t j = 0; j < cols; ++j) {
for (size_t i = 0; i < rows; ++i) {
temp[i] = data[i][j];
}
FFT(temp);
for (size_t i = 0; i < rows; ++i) {
data[i][j] = temp[i];
}
}
}
int main() {
// Misol uchun 2D tasvir (matrix)
ComplexMatrix image = {
// Tasvir ma'lumotlari bilan to'ldiring
};
FFT2D(image);
// Natijani chop etish
for (const auto& row : image) {
for (const auto& val : row) {
std::cout << val << " ";
}
std::cout << std::endl;
}
return 0;
}
Ushbu kodda FFT funksiyasi va bitReverse funksiyasining aniq kodlari taqdim etilmagan. Bu funksiyalar murakkab matematik hisob-kitoblarni talab qiladi va ularni to'liq tushunish va amalga oshirish uchun chuqur bilim kerak bo'ladi. Shuningdek, bu kod namunasi ikki o'lchovli tasvirlarni spektral almashtirishning umumiy jarayonini ko'rsatadi, lekin bu jarayonning barcha qismlarini qamrab olmaydi.
DCT, Hadamard, Haar va Daubechies almashtirishlarini amalga oshirish uchun har bir algoritmining o'ziga xos xususiyatlarini hisobga olish kerak bo'ladi, va ularning har biri alohida yondashuvni talab qilishi mumkin. Shuningdek, ushbu kodni ishlatishdan oldin OpenMP kutubxonasining o'rnatilgan bo'lishi va C++ kompilyatoringiz OpenMPni qo'llab-quvvatlayotganiga ishonch hosil qiling.
c) tasvirlarni spektral sohada filerlash;
#include
#include
#include
#include
#include
typedef std::complex Complex;
typedef std::vector> ComplexMatrix;
// 1D FFT va invers FFT funksiyalari (taqdim etilmagan)
// 2D FFT
void FFT2D(ComplexMatrix& data, bool inverse = false) {
size_t rows = data.size();
size_t cols = data[0].size();
// Apply FFT to each row
#pragma omp parallel for
for (size_t i = 0; i < rows; ++i) {
FFT(data[i], inverse);
}
// Apply FFT to each column
ComplexVector temp(rows);
#pragma omp parallel for private(temp)
for (size_t j = 0; j < cols; ++j) {
for (size_t i = 0; i < rows; ++i) {
temp[i] = data[i][j];
}
FFT(temp, inverse);
for (size_t i = 0; i < rows; ++i) {
data[i][j] = temp[i];
}
}
}
// Spektral filtrlash funksiyasi
void spectralFilter(ComplexMatrix& data) {
// Bu yerda filtrlash algoritmini qo'llang
// Masalan, past o'tkazgich filtri yoki boshqa turdagi filtrlarni qo'llash mumkin
// ...
}
int main() {
// Misol uchun 2D tasvir (matrix)
ComplexMatrix image = {
// Tasvir ma'lumotlari bilan to'ldiring
};
// FFT qo'llash
FFT2D(image);
// Spektral filtrlash
spectralFilter(image);
// Invers FFT qo'llash
FFT2D(image, true);
// Natijani chop etish
for (const auto& row : image) {
for (const auto& val : row) {
std::cout << val.real() << " "; // Faqat real qismni chop etish
}
std::cout << std::endl;
}
return 0;
}
Bu kodda FFT funksiyasi va spectralFilter funksiyasining aniq kodlari taqdim etilmagan. FFT funksiyasi murakkab matematik hisob-kitoblarni talab qiladi va bu funksiyaning to'liq tushunilishi va amalga oshirilishi uchun chuqur bilim kerak. Spektral filtrlash uchun esa, ma'lum bir frekans diapazonlarini olib tashlash yoki kamaytirish kerak bo'ladi, bu esa sizning spektral filtrlash talablaringizga bog'liq.
d) tasvirlarni siqish.
#include
#include
#include
#include
typedef std::vector> Matrix;
// DCT va IDCT funksiyalari
void DCT(Matrix& data, bool inverse = false) {
// DCT yoki invers DCT algoritmini shu yerda amalga oshiring
// ...
}
// Ikki o'lchamli DCT
void DCT2D(Matrix& data, bool inverse = false) {
size_t rows = data.size();
size_t cols = data[0].size();
// Apply DCT to each row
#pragma omp parallel for
for (size_t i = 0; i < rows; ++i) {
DCT(data[i], inverse);
}
// Apply DCT to each column
std::vector temp(rows);
#pragma omp parallel for private(temp)
for (size_t j = 0; j < cols; ++j) {
for (size_t i = 0; i < rows; ++i) {
temp[i] = data[i][j];
}
DCT(temp, inverse);
for (size_t i = 0; i < rows; ++i) {
data[i][j] = temp[i];
}
}
}
// Tasvirni siqish
void compressImage(Matrix& image) {
// DCT qo'llash
DCT2D(image);
// Muayyan frekans komponentlarini olib tashlash yoki kamaytirish
// Bu yerda siqish algoritmini qo'llang
// ...
// Invers DCT qo'llash
DCT2D(image, true);
}
int main() {
// Misol uchun 2D tasvir (matrix)
Matrix image = {
// Tasvir ma'lumotlari bilan to'ldiring
};
compressImage(image);
// Natijani chop etish
for (const auto& row : image) {
for (const auto& val : row) {
std::cout << val << " ";
}
std::cout << std::endl;
}
return 0;
}
Bu kodda DCT funksiyasining aniq kodlari taqdim etilmagan. DCT algoritmini amalga oshirish uchun matematik hisob-kitoblar talab etiladi. Shuningdek, siqish jarayonida qanday frekans komponentlarini olib tashlash yoki kamaytirish kerakligi sizning tasvir siqish talablaringizga bog'liq bo'ladi.
Adabiyotlar ro’yxat
Khujayorov I.Sh, Islomov Sh.Z, Nuriev S.A, Ochilov M.M, " Parallel Solving Tasks of Digital Image Processing" International Journal on Recent and Innovation Trends in Computing and Communication Volume: 4 Issue: 6. 2016 335 - 339 p.
http://ccfit.nsu.ru/arom/data/openmp.pdf
https://parallel.ru/tech/tech_dev/openmp.html
|
|
Bosh sahifa
Aloqalar
Bosh sahifa
Laboratoriya ishi №2 Openmp parallellashtirish kutubxonasi bilan tanishish va uning yordamida parallel dasturlar tuzush
|