ExtImg.at<float>(i, 0) = ExtImg.at<float>(i, 1);
ExtImg.at<float>(i, img.cols + 1) = ExtImg.at<float>(i, img.cols);
}
for (int j = 1; j < img.cols + 1; j++) {
ExtImg.at<float>(0, j) = ExtImg.at<float>(1, j);
ExtImg.at<float>(img.rows + 1, j) = ExtImg.at<float>(img.rows, j);
}
ExtImg.at<float>(0, 0) = ExtImg.at<float>(1, 1);
ExtImg.at<float>(0, img.cols + 1) = ExtImg.at<float>(1, img.cols);
ExtImg.at<float>(img.rows + 1, 0) = ExtImg.at<float>(img.rows, 1);
ExtImg.at<float>(img.rows + 1, img.cols + 1) = ExtImg.at<float>(img.rows, img.cols);
// next page continued....
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
vector<float> mask;
for (int u = 0; u < size; u++) {
for (int v = 0; v < size; v++)
mask.push_back(ExtImg.at<float>(i + u, j + v));
}
cv::sort(mask, mask, SORT_EVERY_ROW); // cv:: writing to distinguish from std::sort()
dst.at<uchar>(i, j) = (uchar)mask[4];
}
}
}
int main()
{
Mat gray = imread("../image/Boat-noise.tif", IMREAD_GRAYSCALE);
CV_Assert(gray.data);
Mat med_img1, med_img2;
namedWindow("Original Image", WINDOW_AUTOSIZE);
moveWindow("Original Image", 200, 200);
imshow("Original Image", gray);
medianFilter(gray, med_img1, 3); // Median Filtering using User Function
namedWindow("median-User", WINDOW_AUTOSIZE);
moveWindow("median-User", 600, 200);
imshow("median-User", med_img1);
medianBlur(gray, med_img2, 3); // Median Filtering using OpenCV Function
namedWindow("median-OpenCV", WINDOW_AUTOSIZE);
moveWindow("median-OpenCV", 1000, 200);
imshow("median-OpenCV", med_img2);
waitKey();
return 0;
}
8. Преобразование обработки домена / Transform Domain Processing
Пространственная частота (Мекансал фреканс)/ Spatial Frequency (Mekansal frekans)
•
Hertz (Hz)
–
единица частоты
–
Количество раз, чтобы вибрировать в 1 секунду
•
При обработке изображений (image processing) используется понятие пространственной частоты (spatial frequency)
•
Определение степени яркости пикселя
sec
sec
sec
•
Пространственная частота (spatial frequency)
–
Низкочастотная пространственная область
•
В области, где яркость пикселей(pixel brightness) практически не изменяется или постепенно изменяется
•
Фоновая часть изображений.
–
Высокочастотная пространственная область
•
Яркость пикселей (pixel brightness) быстро меняется
Краевая часть изображений
Низкая частота
Высокая частота
•
Что делать, если вы разделяете изображения (image) по частотной области(frequency domain)?
–
Изображение с удаленными высокочастотными компонентами (high frequency components)
☞
Изображение (image) с размытым краем (edge)
–
Изображение снято только с высокочастотными компонентами (high frequency components)
☞
Изображение, включающее только край (edge), то есть edge image
•
Преобразование частоты (Frequency Transform)
Входное изображение
Частота
Трансформировать
Частота
Обратное преобразование
Частота
Коэффициенты
Преобразование Фурье / Fourier Transform
●
Пространственная область → Ширина частотной области, высота, размер изображения: N
(Spatial Domain → Frequency Domain width, height size of image: N)
●
Частотная область → Ширина пространственной области, высота, размер изображения:
N
(Frequency Domain → Spatial Domain width, height size of image: N)
(a) Входное изображение
(b) Изображение частоты
(c) Изображение перетасованной частоты
Частота будет увеличиваться от центра изображения к краям.
Фурье
Трансформировать
Фурье
Обратный
Трансформировать
Дискретное косинусное преобразование / (DCT) Discrete Cosine Transform(DCT)
●
Пространственная область → Ширина частотной области, высота, размер изображения:
N
(Spatial Domain → Frequency Domain width, height size of image: N)
●
Частотная область → Ширина пространственной области, высота, размер изображения:
N
(Frequency Domain → Spatial Domain width, height size of image: N)
Ленна 16x16 Блок пикселей / Lenna 16x16 Block Pixels
suratyny oňarmaly, doly goup bilmedim.
Ленна 16x16 Блок коэффициентов DCT / Lenna 16x16 Block DCT Coefficients
●
Ленна 16x16 Блок коэффициентов DCT
●
Смещение=128
179-daky Suraty goýup bilmedim
Высокий (High)
180-däki Suraty goýup bilmedim
Дискретное косинусное преобразование (DCT) / Discrete Cosine Transform(DCT)
// Discrete Cosine Transform(DCT) Program
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat DCT_block(Mat g) // Forward DCT
{
Mat dst(g.size(), g.type());
int N = g.rows, M = g.cols;
for (int k = 0; k < N; k++) {
for (int l = 0; l < M; l++) {
float sum = 0;
for (int n = 0; n < N; n++) {
for (int m = 0; m < M; m++) {
float theta1 = (float)((2 * n + 1) * k * CV_PI / (2 * N));
float theta2 = (float)((2 * m + 1) * l * CV_PI / (2 * M));
sum += g.at<float>(n, m) * cos(theta1) * cos(theta2);
}
}
float ck = (k) ? sqrt(2.0f / N) : sqrt(1.0f / N);
float cl = (l) ? sqrt(2.0f / M) : sqrt(1.0f / M);
dst.at<float>(k, l) = ck * cl * sum;
}
}
return dst;
}
// next page continued....
Mat IDCT_block(Mat f) // Inverse DCT
{
Mat dst(f.size(), f.type());
int N = f.rows, M = f.cols;
for (int n = 0; n < N; n++) {
for (int m = 0; m < M; m++) {
float sum = 0;
for (int k = 0; k < N; k++) {
for (int l = 0; l < M; l++) {
float theta1 = (float)((2 * n + 1) * k * CV_PI / (2 * N));
float theta2 = (float)((2 * m + 1) * l * CV_PI / (2 * M));
float ck = (k) ? sqrt(2.0f / N) : sqrt(1.0f / N);
float cl = (l) ? sqrt(2.0f / M) : sqrt(1.0f / M);
sum += ck * cl * f.at<float>(k, l) * cos(theta1) * cos(theta2);
}
}
dst.at<float>(n, m) = sum;
}
}
return dst;
}
void DCT_2D(Mat img, Mat& dst, int N, int M, int dir)
{
dst = Mat(img.size(), CV_32F);
img.convertTo(img, CV_32F);
// next page continued....
for (int bi = 0; bi < img.rows; bi += N) {
for (int bj = 0; bj < img.cols; bj += M) {
Rect rect(Point(bj, bi), Size(M, N));
Mat block = img(rect);
Mat new_block = (dir == 0) ? DCT_block(block) : IDCT_block(block);
new_block.copyTo(dst(rect));
}
}
}
int main()
{
Mat image = imread("../image/lena_std.tif", IMREAD_GRAYSCALE);
CV_Assert(image.data);
Mat m_dct, m_idct;
DCT_2D(image, m_dct, 8, 8, 0);
DCT_2D(m_dct, m_idct, 8, 8, 1);
m_idct.convertTo(m_idct, CV_8U);
namedWindow("Original Image", WINDOW_AUTOSIZE);
namedWindow("Inverse DCT", WINDOW_AUTOSIZE);
moveWindow("Original Image", 200, 200), moveWindow("Inverse DCT", 800, 200);
imshow("Original Image", image), imshow("Inverse DCT", m_idct);
Rect rect(0, 0, 8, 8);
cout << “First 8x8 Block Original Image Elements" << endl;
cout << image(rect) << endl << endl;
cout << “First 8x8 Block DCT Coefficients" << endl;
cout << m_dct(rect) << endl;
waitKey();
}