Ask Your Question

Revision history [back]

Converting JS oil painting filter to OpenCV C++

A while back I followed a tutorial (or maybe an answer from another question or something) on how to apply an oil painting filter (http://jsfiddle.net/loktar/96arS/) to an image and write it to a canvas using javascript. Now I want to achieve the same effect using openCV and C++.

I was also using: http://supercomputingblog.com/graphics/oil-painting-algorithm/ as a reference for the psuedo-code.

So far I am as far as reading the image and iterating through the pixels and finding the intensity values.

int main()
{
    Mat im = imread(...);
    Mat outline;
    Mat paint;

    int intensityLUT[im.rows][im.cols];
    int rgbLUT[im.rows][im.cols][3]; //r/g/b
    int intensity = 20;
    int radius = 3;
    int pixelIntensityValue[100];
    int pixelIntensityCount[100][4];

    for(int y = 0; y < im.rows; y++)
    {
        for (int x = 0; x < im.cols; x++)
        {
            int r = im.at<cv::Vec3b>(y,x)[0];
            int g = im.at<cv::Vec3b>(y,x)[1];
            int b = im.at<cv::Vec3b>(y,x)[2];

            intensityLUT[y][x] = round(  ((r+g+b)/3)  * intensity/255);

            rgbLUT[y][x][0] = r;
            rgbLUT[y][x][1] = g;
            rgbLUT[y][x][2] = b;

        }
    } //first itteration to get rgb values

    for(int y = 0; y < im.rows; y++)
    {
        for (int x = 0; x < im.cols; x++) //for each pixel
        {
            for(int yy = -radius; yy <= radius; yy++)
            {
                for(int xx = -radius; xx <= radius; xx++)
                {
                    if(y + yy > 0 && y+yy < im.rows && x+xx > 0 && x+xx < im.cols)
                    {
                        int intensityVal = intensityLUT[y+yy][x+xx];
                        pixelIntensityCount[intensityVal][0] ++; // priority
                        pixelIntensityCount[intensityVal][1] += rgbLUT[y+yy][x+xx][0]; //red
                        pixelIntensityCount[intensityVal][2] += rgbLUT[y+yy][x+xx][1]; //green
                        pixelIntensityCount[intensityVal][3] += rgbLUT[y+yy][x+xx][2]; //blue

                    }
             //
             //pixelIntensityCount.sort(function (a, b)
             //{
             //return b.val - a.val;
             //});

             //var curMax = pixelIntensityCount[0].val,
             //dIdx = (y*w+x) * 4;

             //destPixData[dIdx] = ~~ (pixelIntensityCount[0].r / curMax);
             //destPixData[dIdx+1] = ~~ (pixelIntensityCount[0].g / curMax);
             //destPixData[dIdx+2] = ~~ (pixelIntensityCount[0].b / curMax);
             //destPixData[dIdx+3] = 255;
        }
    }
    //imshow("Result", paint);
    waitKey();
    return 0;
}

so the part I'm stuck on is converting the array sort function and then creating a new matrix to store the image for showing / writing at the end. I think apart from that it should work? Can anyone suggest to me, the correct way to do that please?

Thanks.

Converting JS oil painting filter to OpenCV C++C++ Sort Array and Create Matrix

A while back I followed a tutorial (or maybe an answer from another question or something) on how to apply an oil painting filter (http://jsfiddle.net/loktar/96arS/) to an image and write it to a canvas using javascript. Now I want to achieve the same effect using openCV and C++.

I was also using: http://supercomputingblog.com/graphics/oil-painting-algorithm/ as a reference for the psuedo-code.

So far I am as far as reading the image and iterating through the pixels and finding the intensity values.

int main()
{
    Mat im = imread(...);
    Mat outline;
    Mat paint;

    int intensityLUT[im.rows][im.cols];
    int rgbLUT[im.rows][im.cols][3]; //r/g/b
    int intensity = 20;
    int radius = 3;
    int pixelIntensityValue[100];
    int pixelIntensityCount[100][4];

    for(int y = 0; y < im.rows; y++)
    {
        for (int x = 0; x < im.cols; x++)
        {
            int r = im.at<cv::Vec3b>(y,x)[0];
            int g = im.at<cv::Vec3b>(y,x)[1];
            int b = im.at<cv::Vec3b>(y,x)[2];

            intensityLUT[y][x] = round(  ((r+g+b)/3)  * intensity/255);

            rgbLUT[y][x][0] = r;
            rgbLUT[y][x][1] = g;
            rgbLUT[y][x][2] = b;

        }
    } //first itteration to get rgb values

    for(int y = 0; y < im.rows; y++)
    {
        for (int x = 0; x < im.cols; x++) //for each pixel
        {
            for(int yy = -radius; yy <= radius; yy++)
            {
                for(int xx = -radius; xx <= radius; xx++)
                {
                    if(y + yy > 0 && y+yy < im.rows && x+xx > 0 && x+xx < im.cols)
                    {
                        int intensityVal = intensityLUT[y+yy][x+xx];
                        pixelIntensityCount[intensityVal][0] ++; // priority
                        pixelIntensityCount[intensityVal][1] += rgbLUT[y+yy][x+xx][0]; //red
                        pixelIntensityCount[intensityVal][2] += rgbLUT[y+yy][x+xx][1]; //green
                        pixelIntensityCount[intensityVal][3] += rgbLUT[y+yy][x+xx][2]; //blue

                    }
             //
             //pixelIntensityCount.sort(function (a, b)
             //{
             //return b.val - a.val;
             //});

             //var curMax = pixelIntensityCount[0].val,
             //dIdx = (y*w+x) * 4;

             //destPixData[dIdx] = ~~ (pixelIntensityCount[0].r / curMax);
             //destPixData[dIdx+1] = ~~ (pixelIntensityCount[0].g / curMax);
             //destPixData[dIdx+2] = ~~ (pixelIntensityCount[0].b / curMax);
             //destPixData[dIdx+3] = 255;
        }
    }
    //imshow("Result", paint);
    waitKey();
    return 0;
}

so the part I'm stuck on is converting the array sort function and then creating a new matrix to store the image for showing / writing at the end. I think apart from that it should work? Can anyone suggest to me, the correct way to do that please?

Thanks.

C++ Sort Array and Create Matrix

A while back I followed a tutorial (or maybe an answer from another question or something) on how to apply an oil painting filter (http://jsfiddle.net/loktar/96arS/) to an image and write it to a canvas using javascript. Now I want to achieve the same effect using openCV and C++.

I was also using: http://supercomputingblog.com/graphics/oil-painting-algorithm/ as a reference for the psuedo-code.

So far I am as far as reading the image and iterating through the pixels and finding the intensity values.

int main()
{
    Mat im = imread(...);
    Mat outline;
    Mat paint;

    int intensityLUT[im.rows][im.cols];
    int rgbLUT[im.rows][im.cols][3]; //r/g/b
    int intensity = 20;
    int radius = 3;
    int pixelIntensityValue[100];
    int pixelIntensityCount[100][4];

    for(int y = 0; y < im.rows; y++)
    {
        for (int x = 0; x < im.cols; x++)
        {
            int r = im.at<cv::Vec3b>(y,x)[0];
            int g = im.at<cv::Vec3b>(y,x)[1];
            int b = im.at<cv::Vec3b>(y,x)[2];

            intensityLUT[y][x] = round(  ((r+g+b)/3)  * intensity/255);

            rgbLUT[y][x][0] = r;
            rgbLUT[y][x][1] = g;
            rgbLUT[y][x][2] = b;

        }
    } //first itteration to get rgb values

    for(int y = 0; y < im.rows; y++)
    {
        for (int x = 0; x < im.cols; x++) //for each pixel
        {
            for(int yy = -radius; yy <= radius; yy++)
            {
                for(int xx = -radius; xx <= radius; xx++)
                {
                    if(y + yy > 0 && y+yy < im.rows && x+xx > 0 && x+xx < im.cols)
                    {
                        int intensityVal = intensityLUT[y+yy][x+xx];
                        pixelIntensityCount[intensityVal][0] ++; // priority
                        pixelIntensityCount[intensityVal][1] += rgbLUT[y+yy][x+xx][0]; //red
                        pixelIntensityCount[intensityVal][2] += rgbLUT[y+yy][x+xx][1]; //green
                        pixelIntensityCount[intensityVal][3] += rgbLUT[y+yy][x+xx][2]; //blue

                    }
             //
             //pixelIntensityCount.sort(function (a, b)
             //{
             //return b.val - a.val;
             //});

             //var curMax = pixelIntensityCount[0].val,
             //dIdx = (y*w+x) * 4;

             //destPixData[dIdx] = ~~ (pixelIntensityCount[0].r / curMax);
             //destPixData[dIdx+1] = ~~ (pixelIntensityCount[0].g / curMax);
             //destPixData[dIdx+2] = ~~ (pixelIntensityCount[0].b / curMax);
             //destPixData[dIdx+3] = 255;
        }
    }
    //imshow("Result", paint);
    waitKey();
    return 0;
}

so the part I'm stuck on is converting the array sort function and then creating a new matrix to store the image for showing / writing at the end. I think apart from that it should work? Can anyone suggest to me, the correct way to do that please?

Thanks.