Untitled
unknown
plain_text
14 days ago
11 kB
3
Indexable
#include <stdio.h> using namespace std; #include <iostream> #include <cmath> // OpenCV includes #include <opencv2/opencv.hpp> //#include "opencv2/core.hpp" //#include "opencv2/highgui.hpp" using namespace cv; //utworzenie okna o nazwie name w punkcie (x,y) (lewy górny róg okna) void CreateWindowAt(const char* name, int x, int y) { namedWindow(name, WINDOW_AUTOSIZE); moveWindow(name, x, y); } // wyświetlenie obrazu img w oknie o nazwie name położonego w punkcie (x,y) (lewy górny róg okna) void ShowImageAt(const char* name, Mat img, int x, int y) { CreateWindowAt(name, x, y); imshow(name, img); } // wczytanie obrazu z pliku name do macierzy img int read_image(const char* name, Mat* img) { *img = imread(name); if (!(*img).data) { cout << "Error! Cannot read source file. Press ENTER."; waitKey(); // czekaj na naciśnięcie klawisza return(-1); } return 0; } int show_masked_image = 0; Mat srcImage; // obraz wejściowy Mat greyImage; // obraz po konwersji do obrazu w odcieniach szarości Mat maskImage; Mat secondImage; //funkcja konwertująca obraz src na obraz dst w odcieniach szarości void convertToGrey(Mat src, Mat dst) { //pętla po wszystkich pikselach obrazu for (int x = 0; x < src.cols; x++) for (int y = 0; y < src.rows; y++) { //pobranie do zmiennej pixelColor wszystkich 3 składowych koloru piksela Vec3b pixelColor = src.at<Vec3b>(y, x); //konwersja na kolor szary; pixelColor[0] składowa B, pixelColor[1] składowa G, pixelColor[2] składowa R int gray = (int)(0.299f * pixelColor[2] + 0.587f * pixelColor[1] + 0.114f * pixelColor[0]); for (int i = 0; i < 3; i++) // for BGR elements pixelColor[i] = gray; //ustawienie obliczonej wartości piksela na obrazie wyjściowym dst.at<Vec3b>(y, x) = pixelColor; } } //fukcja zmieniająca kontrast i jasność obrazu src i umieszczająca wynik na obrazie dst void BrightnessAndContrast(Mat src, Mat dst, float A, int B) { //pętla po wszystkich pikselach obrazu for (int x = 0; x < src.cols; x++) for (int y = 0; y < src.rows; y++) { Vec3b pixelColor = src.at<Vec3b>(y, x); for (int i = 0; i < 3; i++) // for BGR elements { float pixelValue = A * pixelColor[i] + B; // Umieściłem tutaj odpowieni kod // Normalizacja if (pixelValue > 255) pixelValue = 255; else if (pixelValue < 0) pixelValue = 0; pixelColor[i] = (uchar)pixelValue; } dst.at<Vec3b>(y, x) = pixelColor; } } // wartość jasności (B) int brightness_value = 100; //wartość kontrastu (A) int alpha_value = 200; // funkcja związana z suwakiem, wywoływana przy zmianie jego położenia void BrightnessAndContrastCallBack(int pos, void* userdata) { Mat* img = (Mat*)userdata; //wywołanie funkcji realizującej zmianę jasności i kontrastu BrightnessAndContrast BrightnessAndContrast(srcImage, *img, alpha_value / 100.0f, brightness_value - 200); imshow("Bright Image", *img); } //LUT - operacje potęgowe uchar powerLUT[256]; void preparePowerLUT(float alpha) { const int Jmax = 255; for (int i = 0; i < 256; i++) { float normalizedValue = (float)i / Jmax; float correctedValue = Jmax * pow(normalizedValue, alpha); if (correctedValue > Jmax) correctedValue = Jmax; else if (correctedValue < 0) correctedValue = 0; powerLUT[i] = (uchar)correctedValue; // Print values every 16 steps to keep the output manageable if (i % 16 == 0 || i == 255) { cout << i << "\t" << (int)powerLUT[i] << endl; } } cout << endl; } void applyPowerOperation(Mat src, Mat dst) { for (int x = 0; x < src.cols; x++) for (int y = 0; y < src.rows; y++) { Vec3b pixelColor = src.at<Vec3b>(y, x); Vec3b newPixelColor; //pobranie do zmiennej pixelColor wszystkich 3 składowych koloru piksela for (int i = 0; i < 3; i++) // for BGR elements { newPixelColor[i] = powerLUT[pixelColor[i]]; } dst.at<Vec3b>(y, x) = newPixelColor; } } // wartość alpha int power_alpha_value = 100; // 1.0 (100/100) // Funkcja callback dla suwaka operacji potęgowania void PowerOperationCallBack(int pos, void* userdata) { Mat* img = (Mat*)userdata; // Obliczenie wartości alpha z zakresu 0.1 - 3.0 float alpha = power_alpha_value / 100.0f; // Przygotowanie tablicy LUT z aktualną wartością alpha preparePowerLUT(alpha); // Zastosowanie operacji potęgowania z użyciem LUT applyPowerOperation(srcImage, *img); // Aktualizacja wyświetlanego obrazu imshow("Power Operation", *img); } /// 3.1. Funkcja maskowania obrazu void applyMasking(Mat srcImg, Mat maskImg, Mat dstImg) { // Sprawdzenie czy wymiary obrazów są zgodne if (srcImg.cols != maskImg.cols || srcImg.rows != maskImg.rows) { cout << "Error: Source and mask image dimensions must match!" << endl; return; } for (int x = 0; x < srcImg.cols; x++) for (int y = 0; y < srcImg.rows; y++) { Vec3b srcPixel = srcImg.at<Vec3b>(y, x); Vec3b maskPixel = maskImg.at<Vec3b>(y, x); Vec3b resultPixel; for (int i = 0; i < 3; i++) // dla każdego kanału BGR { // Normalizacja wartości maski do zakresu 0-1 float maskValue = maskPixel[i] / 255.0f; // Mnożenie piksela źródłowego przez wartość maski float resultValue = srcPixel[i] * maskValue; // Normalizacja wyniku if (resultValue > 255) resultValue = 255; else if (resultValue < 0) resultValue = 0; resultPixel[i] = (uchar)resultValue; } dstImg.at<Vec3b>(y, x) = resultPixel; } } // 3.2. Funkcja mieszania obrazów void blendImages(Mat img1, Mat img2, Mat dstImg, float blendFactor) { // Sprawdzenie czy wymiary obrazów są zgodne if (img1.cols != img2.cols || img1.rows != img2.rows) { cout << "Error: Both images must have the same dimensions for blending!" << endl; return; } for (int x = 0; x < img1.cols; x++) for (int y = 0; y < img1.rows; y++) { Vec3b pixel1 = img1.at<Vec3b>(y, x); Vec3b pixel2 = img2.at<Vec3b>(y, x); Vec3b blendedPixel; for (int i = 0; i < 3; i++) // dla każdego kanału BGR { // Wzór: Jwy(x,y) = a*J1(x,y) + (1-a)*J2(x,y) float blendedValue = blendFactor * pixel1[i] + (1.0f - blendFactor) * pixel2[i]; // Normalizacja wyniku if (blendedValue > 255) blendedValue = 255; else if (blendedValue < 0) blendedValue = 0; blendedPixel[i] = (uchar)blendedValue; } dstImg.at<Vec3b>(y, x) = blendedPixel; } } // Wartość współczynnika mieszania int blend_factor_value = 50; // domyślnie 0.5 (50/100) // Funkcja callback dla suwaka mieszania obrazów void BlendImagesCallBack(int pos, void* userdata) { Mat* img = (Mat*)userdata; // Obliczenie wartości współczynnika mieszania z zakresu 0.0 - 1.0 float blendFactor = blend_factor_value / 100.0f; cout << "Current blend factor: " << blendFactor << endl; // Zastosowanie mieszania obrazów blendImages(srcImage, maskImage, *img, blendFactor); // Aktualizacja wyświetlanego obrazu imshow("Blended Image", *img); } // Funkcja callback dla pokazania maskowanego obrazu void ShowMaskedImageCallBack(int pos, void* userdata) { Mat* img = (Mat*)userdata; if (show_masked_image == 1) // Apply the mask only if the slider is set to 1 { applyMasking(srcImage, maskImage, *img); } else // Reset to the original image if the slider is set to 0 { srcImage.copyTo(*img); } // Update the displayed image imshow("Masked Image", *img); } int main() { // wczytanie obrazu do srcImage int r = read_image("Samples/zebra.jpg", &srcImage); if (r == -1) return(-1); ShowImageAt("Source image", srcImage, 0, 0); // Wczytanie drugiego obrazu (maska) r = read_image("Samples/maska.jpg", &maskImage); if (r == -1) { // Jeśli nie można wczytać maski, stwórz prostą maskę (ciemniejsza na brzegach, jaśniejsza w środku) maskImage = Mat(srcImage.size(), srcImage.type(), Scalar(0, 0, 0)); int centerX = maskImage.cols / 2; int centerY = maskImage.rows / 2; int radius = std::min(centerX, centerY); for (int x = 0; x < maskImage.cols; x++) { for (int y = 0; y < maskImage.rows; y++) { // Obliczenie odległości od środka float distance = sqrt(pow(x - centerX, 2) + pow(y - centerY, 2)); // Wartość maski maleje wraz z odległością od środka float value = std::max(0.0f, 1.0f - distance / radius); Vec3b pixelValue; pixelValue[0] = pixelValue[1] = pixelValue[2] = (uchar)(value * 255); maskImage.at<Vec3b>(y, x) = pixelValue; } } } ShowImageAt("Mask image", maskImage, 900, 0); // Grey image Mat greyImage; srcImage.copyTo(greyImage); convertToGrey(srcImage, greyImage); ShowImageAt("Grey image", greyImage, 450, 0); // zmiana jasności i kontrastu Mat brightImage; //zainicjowanie obrazu brightImage obrazem srcImage srcImage.copyTo(brightImage); CreateWindowAt("Bright Image", 0, 335); //tworzenie suwaka o nazwie "Contrast" związanego z oknem "Bright Image", alpha_value wartość całkowita, która będzie zmieniana przez trackbar, 700 maksymalna wartość na suwaku, // BrightnessAndContrastCallBack funkcja wywoływana przy każdej zmianie pozycji suwaka, brightImage dane przekazywane do callback createTrackbar("Contrast", "Bright Image", &alpha_value, 700, BrightnessAndContrastCallBack, &brightImage); //analogicznie dodaj TrackBar dla jasności (brightness) BrightnessAndContrastCallBack(0, &brightImage); //dodanie TrackBar dla jasności (brightness) createTrackbar("Brightness", "Bright Image", &brightness_value, 400, BrightnessAndContrastCallBack, &brightImage); // Operacja potęgowania z użyciem LUT Mat powerImage; srcImage.copyTo(powerImage); CreateWindowAt("Power Operation", 450, 335); // Utworzenie suwaka dla parametru alpha operacji potęgowania (zakres 0.1 - 3.0) createTrackbar("Alpha", "Power Operation", &power_alpha_value, 300, PowerOperationCallBack, &powerImage); // Wywołanie początkowe dla inicjalizacji obrazu PowerOperationCallBack(0, &powerImage); // 3.1 Operacja maskowania obrazu Mat maskedImage; srcImage.copyTo(maskedImage); CreateWindowAt("Masked Image", 0, 670); // Dodanie przycisku do pokazania maskowanego obrazu createTrackbar("Show", "Masked Image", &show_masked_image, 1, ShowMaskedImageCallBack, &maskedImage); // Inicjalne wywołanie maskowania ShowMaskedImageCallBack(0, &maskedImage); // 3.2 Operacja mieszania obrazów Mat blendedImage; srcImage.copyTo(blendedImage); CreateWindowAt("Blended Image", 450, 670); // Utworzenie suwaka dla współczynnika mieszania (zakres 0.0 - 1.0) createTrackbar("Blend Factor", "Blended Image", &blend_factor_value, 100, BlendImagesCallBack, &blendedImage); // Inicjalne wywołanie mieszania BlendImagesCallBack(0, &blendedImage); waitKey(); }
Editor is loading...
Leave a Comment