Untitled
unknown
plain_text
6 months ago
11 kB
4
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