Larsus
Larsus

Reputation: 111

How to implement a Laplace filter in C++

I implemented my own Laplace filter but it does not look like the Laplace filter in Gimp for example. What is wrong?

My attempt enter image description here

Gimp enter image description here

cv::Mat ImageManipulation::mylaplace_filter(cv::Mat image){
    int laplace_mask[9] = {0, -1, 0, -1, 4, -1, 0, -1, 0};
    int tmp = 0;
    int counter = 0;
    cv::Mat laplaceImage = cv::Mat::ones(image.rows-2,image.cols-2,CV_8U);
    for(int i = 1; i<image.rows-1; i++){
        for(int j = 1; j<image.cols-1; j++){

            for(int k = i-1; k<i+2; k++){
                for(int l = j-1; l<j+2; l++){
                    tmp += laplace_mask[counter] * static_cast<int>(image.at<uchar>(k,l));
                    counter++;
                }
            }
            std::cout << tmp/9 << std::endl;
            laplaceImage.at<uchar>(i-1,j-1) = tmp/9;
            tmp = 0;
            counter = 0;
        }
    }
    return laplaceImage;
}

Upvotes: 2

Views: 4149

Answers (2)

Umanda
Umanda

Reputation: 4843

This is very simple code, this will helps to understand basics

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>

using namespace cv;


int main(int argc, char** argv){

    Mat src_gray, dst;

    Mat src = imread("ball.jpg");
    int kernel = 3;
    Mat filter = (Mat_ <double>(3,3) << 1,1,1,1,-8,1,1,1,1); // Laplace Filter

    filter2D(src, dst, -1, filter);
    imshow("Simple Function", dst);
    imshow("Simple Source", src);

    waitKey(0);

    return 0;
}

Making your own linear filters! https://docs.opencv.org/3.4/d4/dbd/tutorial_filter_2d.html

Laplace Operator https://docs.opencv.org/3.4/d5/db5/tutorial_laplace_operator.html

Upvotes: 0

MeiH
MeiH

Reputation: 1855

You have to change the type of the image "laplaceImage", before getting into the loop, and as @Cris Luengo commented, no need to dividing by 9:

cv::Mat ImageManipulation::mylaplace_filter(cv::Mat image)
{
    int laplace_mask[9] = { 0, -1, 0, -1, 4, -1, 0, -1, 0 };
    int tmp = 0;
    int counter = 0;
    cv::Mat laplaceImage = cv::Mat::ones(image.rows - 2, image.cols - 2, CV_32F);

    for (int i = 1; i < image.rows - 1; i++)
    {
        for (int j = 1; j < image.cols - 1; j++)
        {

            for (int k = i - 1; k < i + 2; k++)
            {
                for (int l = j - 1; l < j + 2; l++)
                {
                    tmp += laplace_mask[counter] * static_cast<int>(image.at<uchar>(k, l));
                    counter++;
                }
            }
            std::cout << tmp << std::endl;
            laplaceImage.at<float>(i - 1, j - 1) = tmp;
            tmp = 0;
            counter = 0;
        }
    }
    return laplaceImage;
}

after that if you want to show "laplaceImage" or save it on hard disk, you can adjust it between 0 and 255, then convert it to CV_8U.

Upvotes: 1

Related Questions