Có gì mới?
Diễn đàn ứng dụng xử lý ảnh công nghiệp trong sản xuất

Đây là một tin nhắn khách mời. Đăng ký một tài khoản miễn phí ngay hôm nay để trở thành một thành viên! Sau khi đăng nhập, bạn sẽ có thể tham gia trang web này bằng cách thêm các chủ đề và bài đăng của riêng bạn, cũng như kết nối với các thành viên khác thông qua hộp thư đến riêng của bạn!

C/C++ Thuật toán nâng cao chất lượng ảnh Coherence Enhancing Diffusion

Ngôn ngữ C/C++

quochuy

Moderator
Green Industry
Tham gia
12/12/2023
Bài viết
8
Điểm
3
Tuổi
44
Nơi ở
Việt Nam
Coherence Enhancing Diffusion (CED) là một phương pháp xử lý ảnh được thiết kế để cải thiện tính nhất quán và cấu trúc của hình ảnh, đặc biệt trong việc làm nổi bật các cạnh và đặc điểm quan trọng trong hình ảnh. Điều này thường được thực hiện bằng cách áp dụng quá trình diffusion (lan truyền) với một hàm mục tiêu đặc biệt để tăng cường thông tin chất lượng trong hình ảnh.

Dưới đây là mô tả tổng quan về thuật toán CED:

  1. Quá trình Diffusion:
    • CED sử dụng quá trình diffusion để lan truyền thông tin trong ảnh. Quá trình này thường được mô tả bằng một phương trình đạo hàm riêng phụ thuộc vào độ chênh lệch giữa các điểm ảnh.
  2. Hàm Mục Tiêu (Objective Function):
    • Một phần quan trọng của CED là việc sử dụng hàm mục tiêu để định rõ mục tiêu của quá trình diffusion. Hàm mục tiêu thường được thiết kế để làm nổi bật cạnh và giữ lại thông tin cấu trúc trong hình ảnh.
  3. Tham Số Điều Khiển:
    • CED thường có các tham số điều khiển như hệ số diffusion, thời gian lan truyền, và các tham số liên quan đến hàm mục tiêu. Điều này cho phép điều chỉnh hiệu suất của thuật toán tùy thuộc vào loại hình ảnh và mục tiêu xử lý cụ thể.
Dưới đây là một ví dụ giả định về cách CED có thể được triển khai trong môi trường C++. Lưu ý rằng đây chỉ là một mô phỏng đơn giản và không thể đại diện cho cài đặt cụ thể của CED:

C++:
#include <iostream>
#include <vector>

// Hàm thực hiện quá trình diffusion với hàm mục tiêu
void coherenceEnhancingDiffusion(std::vector<std::vector<double>>& image, double delta_t, double lambda) {
    int rows = image.size();
    int cols = image[0].size();

    // Lặp qua từng điểm ảnh trong hình ảnh
    for (int i = 1; i < rows - 1; ++i) {
        for (int j = 1; j < cols - 1; ++j) {
            // Tính giá trị mới cho điểm ảnh dựa trên giá trị của các điểm xung quanh
            double new_value = image[i][j] + delta_t * (
                lambda * (image[i - 1][j] + image[i + 1][j] + image[i][j - 1] + image[i][j + 1] - 4 * image[i][j])
                + (1 - lambda) * (image[i - 1][j - 1] + image[i - 1][j + 1] + image[i + 1][j - 1] + image[i + 1][j + 1] - 4 * image[i][j])
            );

            // Cập nhật giá trị của điểm ảnh
            image[i][j] = new_value;
        }
    }
}

int main() {
    // Khởi tạo một ma trận ảnh đơn giản
    std::vector<std::vector<double>> image = {
        {0.0, 0.0, 0.0, 0.0},
        {0.0, 1.0, 1.0, 0.0},
        {0.0, 1.0, 1.0, 0.0},
        {0.0, 0.0, 0.0, 0.0}
    };

    // Thực hiện Coherence Enhancing Diffusion với các tham số delta_t và lambda
    double delta_t = 0.1;
    double lambda = 0.2;
    coherenceEnhancingDiffusion(image, delta_t, lambda);

    // In ra màn hình kết quả sau khi diffusion
    for (const auto& row : image) {
        for (double value : row) {
            std::cout << value << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}

Trong ví dụ này, coherenceEnhancingDiffusion thực hiện quá trình diffusion với một hàm mục tiêu được tạo ra thông qua sự kết hợp của các yếu tố nhất quán và cấu trúc. Điều này có thể được điều chỉnh thông qua các tham số như delta_t và lambda. Tuy nhiên, cài đặt thực tế của CED sẽ phức tạp hơn và đòi hỏi kiến thức chi tiết về thuật toán và xử lý ảnh.
 

hieule

Thành viên BQT
CTO
Admin
Dev Leader
Machine Vision Expert
Green Industry
Tham gia
21/10/2023
Bài viết
24
Điểm
1,039
Nơi ở
Việt Nam
Thuật toán này khá hay, tuy nhiên tốc độ xử lý là một vấn đề của thuật toán này. Vì thế có thể viết tối ưu theo phần cứng (thanh ghi...) hoặc đa luồng với phần mềm.
 
Bình luận

quochuy

Moderator
Green Industry
Tham gia
12/12/2023
Bài viết
8
Điểm
3
Tuổi
44
Nơi ở
Việt Nam
Trong quyển "Anisotropic Diffusion in Image Processing" của tác giả Joachim Weickert có giới thiệu chi tiết về thuật toán này. Đọc chi kỹ có thể học điều chỉnh tham số rất hay.
Sách này mọi @mọi người có thể tải về theo đường link này: Coherence-enhancing diffusion
 
Bình luận

quochuy

Moderator
Green Industry
Tham gia
12/12/2023
Bài viết
8
Điểm
3
Tuổi
44
Nơi ở
Việt Nam
Đây là thuật toán Anisotropic-Diffusion được thực hiện với OpenCv bằng ngôn ngữ C++

C++:
#include <stdio.h>
#include <cmath>
#include <math.h>

#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat src_8uc3_img = cv::imread( "lena.png", CV_LOAD_IMAGE_COLOR );

    if (src_8uc3_img.empty()) {
        printf("Unable to read input file (%s, %d).", __FILE__, __LINE__);
    }

    cv::Mat gray_src_8uc1_img;
    cv::cvtColor(src_8uc3_img, gray_src_8uc1_img, CV_BGR2GRAY);

    cv::Mat gray_32fc1_img;
    gray_src_8uc1_img.convertTo(gray_32fc1_img,CV_32FC1, 1.0 / 255.0);

    cv::Mat dst;
    //cv::Mat dst = gray_32fc1_img.clone();
    gray_32fc1_img.copyTo(dst);

    for(int k = 0 ; k<1000 ; k++) {

    for (int i = 1;i<gray_32fc1_img.rows-1;i++){
        for (int j = 1;j<gray_32fc1_img.cols-1;j++){
         float cN, cS, cE, cW;
         float deltacN, deltacS, deltacE, deltacW;

         deltacN = dst.at<float>(i,j-1) - dst.at<float>(i,j);
         deltacS = dst.at<float>(i,j+1) - dst.at<float>(i,j);
         deltacE = dst.at<float>(i+1,j) - dst.at<float>(i,j);
         deltacW = dst.at<float>(i-1,j) - dst.at<float>(i,j);

         cN = abs(exp(-1 * (deltacN * deltacN / (0.015 * 0.015) )));
         cS = abs(exp(-1 * (deltacS * deltacS / (0.015 * 0.015) )));
         cE = abs(exp(-1 * (deltacE * deltacE / (0.015 * 0.015) )));
         cW = abs(exp(-1 * (deltacW * deltacW / (0.015 * 0.015) )));

         dst.at<float>(i,j) =  dst.at<float>(i,j) * ( 1 - 0.1 *(cN + cS + cE + cW)  )+
                   0.1 *( cN * dst.at<float>(i,j-1) + cS * dst.at<float>(i,j+1)
                        + cE * dst.at<float>(i+1,j) + cW * dst.at<float>(i-1,j) );
        }
    }

 }

    cv::imshow( "Original Valve gray", gray_32fc1_img);
    cv::imshow( "Filtered Valve gray", dst);

    cv::waitKey( 0 ); // wait until keypressed

    return 0;
}

Đây là hình ảnh ban đầu (bên trái) và kết quả (bên phải)
lena.png
 
Bình luận
Top