Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

TRƯỜNG ĐẠI HỌC CÔNG NGHỆ - ĐHQGHN

KHOA ĐIỆN TỬ VIỄN THÔNG

Báo cáo
Lập trình ứng dụng
Buổi 4
Họ tên: Nguyễn Thành Trung
MSV: 21021640
Lớp học phần : ELT2014_21

Giảng viên hướng dẫn: Hoàng Văn Xiêm

Hà Nội, ngày 24 April 2024


Câu 1: Viết hàm tách cạnh Sobel, Canny
Orginal Image

Edge detection result

1
CODE tách cạnh Sobel
#include <opencv2/opencv.hpp>

using namespace cv;


using namespace std;

int main() {
// Đọc hình ảnh từ đĩa
Mat inputImage = imread("C:\\Users\\This PC\\OneDrive -
vnu.edu.vn\\Ảnh\\luffy.webp", IMREAD_GRAYSCALE);

// Kiểm tra xem hình ảnh đã được đọc thành công hay không
if (inputImage.empty()) {
cout << "Image error!" << endl;
return -1;
}

// Kích thước của hình ảnh


int rows = inputImage.rows;
int cols = inputImage.cols;

// Khởi tạo ma trận để lưu trữ kết quả sau khi áp dụng bộ lọc Sobel
và đạo hàm bậc 1
Mat edgeImage(rows, cols, CV_8U);

// Kernel Sobel theo hướng X


int sobelKernelX[3][3] = {
{-1, 0, 1},
{-2, 0, 2},
{-1, 0, 1}
};

// Kernel Sobel theo hướng Y


int sobelKernelY[3][3] = {
{-1, -2, -1},
{0, 0, 0},
{1, 2, 1}
};

// Áp dụng bộ lọc Sobel theo hướng X và Y


for (int i = 1; i < rows - 1; i++) {
for (int j = 1; j < cols - 1; j++) {
int sumX = 0;
int sumY = 0;

for (int m = -1; m <= 1; m++) {


for (int n = -1; n <= 1; n++) {
sumX += inputImage.at<uchar>(i + m, j + n) *
sobelKernelX[m + 1][n + 1];
sumY += inputImage.at<uchar>(i + m, j + n) *
sobelKernelY[m + 1][n + 1];
}
}

// Tính toán đạo hàm bậc 1 (gradient)


int gradient = abs(sumX) + abs(sumY); // Gradient xấp xỉ
edgeImage.at<uchar>(i, j) = saturate_cast<uchar>(gradient);
}
}

// Hiển thị hình ảnh gốc và kết quả sau khi áp dụng bộ lọc Sobel và

2
đạo hàm bậc 1
namedWindow("Original");
namedWindow("Edge Detection Result");
imshow("Original Image", inputImage);
imshow("Edge Detection Result", edgeImage);

// Chờ nhấn một phím bất kỳ để thoát


waitKey(0);
destroyAllWindows();
return 0;
}

Câu 2: Viết hàm lọc Gausian

Code
#include <cmath>
#include <vector>
#include <iostream>
#include <opencv2/opencv.hpp>

3
using namespace std;
using namespace cv;

// Hàm tính toán hạt nhân Gaussian


vector<vector<double>> createGaussianKernel(int radius, double sigma) {
const double pi = 3.14159265358979323846;
int size = 2 * radius + 1; // Kích thước của hạt nhân
vector<vector<double>> kernel(size, vector<double>(size));
double sum = 0.0; // Tổng các giá trị trong hạt nhân

// Tạo hạt nhân Gaussian


for (int x = -radius; x <= radius; x++) {
for (int y = -radius; y <= radius; y++) {
double exponent = -(x * x + y * y) / (2 * sigma * sigma);
kernel[x + radius][y + radius] = (1 / (2 * pi * sigma * sigma))
* exp(exponent);
sum += kernel[x + radius][y + radius];
}
}

// Chuẩn hóa hạt nhân để tổng bằng 1


for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
kernel[i][j] /= sum;
}
}

return kernel;
}

// Hàm áp dụng lọc Gaussian cho ảnh


void applyGaussianBlur(Mat& inputImage, const vector<vector<double>>&
kernel) {
int radius = kernel.size() / 2;
Mat outputImage = inputImage.clone(); // Tạo bản sao của ảnh gốc để
lưu ảnh đã làm mờ

// Áp dụng lọc Gaussian


for (int i = radius; i < inputImage.rows - radius; i++) {
for (int j = radius; j < inputImage.cols - radius; j++) {
double sum = 0.0;
for (int u = -radius; u <= radius; u++) {
for (int v = -radius; v <= radius; v++) {
sum += kernel[u + radius][v + radius] *
inputImage.at<uchar>(i + u, j + v);
}
}
outputImage.at<uchar>(i, j) = static_cast<uchar>(sum);
}
}

inputImage = outputImage; // Cập nhật ảnh gốc với ảnh đã làm mờ


}

int main() {
// Đọc hình ảnh từ đĩa
Mat inputImage = imread("C:\\Users\\This PC\\OneDrive -
vnu.edu.vn\\Ảnh\\luffy.webp", IMREAD_GRAYSCALE);

// Kiểm tra xem hình ảnh đã được đọc thành công hay không
if (inputImage.empty()) {
cout << "Image error!" << endl;

4
return -1;
}

// Kích thước và độ lệch chuẩn cho hạt nhân Gaussian


int radius = 3;
double sigma = 1.0;

// Tạo hạt nhân Gaussian


vector<vector<double>> kernel = createGaussianKernel(radius, sigma);

// Áp dụng lọc Gaussian cho ảnh


applyGaussianBlur(inputImage, kernel);

// Hiển thị ảnh sau khi đã làm mờ


imshow("Gaussian Blurred Image", inputImage);
waitKey(0);

return 0;
}

Câu 3: Viết hàm Segmentation

5
Code
#include <opencv2/opencv.hpp>
using namespace cv;

void imageSegmentation(const Mat& inputImage) {


// Chuyển đổi ảnh sang mức xám
Mat grayImage;
cvtColor(inputImage, grayImage, COLOR_BGR2GRAY);

// Áp dụng ngưỡng để phân đoạn ảnh


Mat binaryImage;
threshold(grayImage, binaryImage, 128, 255, THRESH_BINARY);

// Hiển thị ảnh gốc và ảnh đã phân đoạn


imshow("Original Image", inputImage);
imshow("Segmented Image", binaryImage);

// Chờ nhấn phím và sau đó đóng cửa sổ


waitKey(0);
destroyAllWindows();
}

int main() {
// Đọc ảnh đầu vào
Mat image = imread(("C:\\Users\\This PC\\OneDrive -
vnu.edu.vn\\Ảnh\\luffy.webp", IMREAD_COLOR);
if (image.empty()) {
cerr << "Error loading image!" << endl;
return 1;

6
}

// Gọi hàm phân đoạn ảnh


imageSegmentation(image);

return 0;
}

Câu 4: tìm hiểu DCT


- Discrete Cosine Transform (DCT) là một kỹ thuật quan trọng trong xử lý tín
hiệu và nén dữ liệu. DCT biến đổi một chuỗi dữ liệu hữu hạn thành tổng của
các hàm cosine dao động ở các tần số khác nhau. Được đề xuất lần đầu tiên
bởi Nasir Ahmed vào năm 1972, DCT được sử dụng rộng rãi trong nhiều lĩnh
vực, từ nén hình ảnh và video đến xử lý âm thanh và truyền hình số
- DCT có một số đặc điểm nổi bật:
o Tính chất nén năng lượng: DCT có khả năng tập trung năng lượng của
tín hiệu vào một số ít hệ số, giúp việc nén dữ liệu trở nên hiệu quả hơn.
o Biến đổi ngược (IDCT): DCT là một phép biến đổi có thể đảo ngược,
cho phép khôi phục dữ liệu gốc từ dữ liệu đã được biến đổi.
o Sử dụng chỉ số thực: Khác với Discrete Fourier Transform (DFT),
DCT chỉ sử dụng số thực, làm cho nó phù hợp hơn với các tín hiệu
thực tế
- Có tám biến thể chuẩn của DCT, trong đó DCT loại II là phổ biến nhất và
thường được gọi đơn giản là DCT. Biến thể ngược của nó, DCT loại III,
thường được gọi là IDCT
- DCT được sử dụng trong các tiêu chuẩn nén như JPEG cho hình ảnh và
MPEG, H.26x cho video. Nó cũng được áp dụng trong các tiêu chuẩn âm
thanh như MP3 và AAC
- Một số thuật toán nhanh đã được phát triển để giảm độ phức tạp tính toán khi
thực hiện DCT. Ví dụ, DCT nguyên số (IntDCT) là một xấp xỉ nguyên của
DCT chuẩn, được sử dụng trong một số tiêu chuẩn quốc tế của ISO/IEC và
ITU-T

You might also like