Ask Your Question

Revision history [back]

You should use opencv function for color conversion. There is no opimization and it is not vey fast... (Check conversion int to float)

int main(int argc, char* argv[])
{
    Mat im=imread("Forest.jpg");
    Mat dst(im.rows,im.cols,CV_8UC3);

    Mat  intensityLUT(im.rows,im.cols,CV_8UC1);
    Mat  rgbLUT(im.rows,im.cols,CV_8UC3); //r/g/b
    int intensity = 20;
    int radius = 3;
    int pixelIntensityValue[100];
    Vec3f pixelIntensityRGB[100];

    cvtColor(im,intensityLUT,CV_RGB2GRAY);
    intensityLUT = intensityLUT *(intensity/255.);


    for(int y = 0; y < im.rows; y++)
    {
        for (int x = 0; x < im.cols; x++) //for each pixel
        {
            vector<int> pixelIntensityCount;
            vector<Vec3f> pixelIntensityRGB;
            pixelIntensityCount.assign(100,0);
            pixelIntensityRGB.assign(100,Vec3f(0,0,0));
            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.at<uchar>(y+yy,x+xx);
                        pixelIntensityCount[intensityVal]++; // priority
                        pixelIntensityRGB[intensityVal] += im.at<Vec3b>(y+yy,x+xx); //red

                    }
                }
            }
            vector<int>::iterator it;
            int pos = distance(pixelIntensityCount.begin(),max_element(pixelIntensityCount.begin(),pixelIntensityCount.end()));
            Vec3b v(pixelIntensityRGB[pos][0] / pixelIntensityCount[pos],pixelIntensityRGB[pos][1] / pixelIntensityCount[pos],pixelIntensityRGB[pos][2] / pixelIntensityCount[pos]);
            dst.at<Vec3b>(y, x) = v;

        }
    }
    imshow("Original", im);
    imshow("Result", dst);
    waitKey();
    return 0;
}

New answer much faster...

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/videoio/videoio.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/highgui.hpp"

#include <iostream>
#include <fstream>
#include <algorithm>
#include <ctype.h>

using namespace cv;
using namespace std;


class ParallelInPaint: public ParallelLoopBody
{
private:
    Mat &imgSrc;
    Mat &dst;
    Mat &intensityLUT;
    bool verbose;
    int radius;
    int intensity;

public:
    ParallelInPaint(Mat& img, Mat &d,Mat &iLuminance,int r):
        imgSrc(img),
        dst(d),
        intensityLUT(iLuminance),
        radius(r),
        verbose(false)
    {}
    void Verbose(bool b){verbose=b;}
    virtual void operator()(const Range& range) const
    {

        int width = imgSrc.cols;
        if (verbose)
            cout << getThreadNum()<<"# :Start from row " << range.start << " to "  << range.end-1<<" ("<<range.end-range.start<<" loops)" << endl;
        vector<int> pixelIntensityCount;
        vector<Vec3f> pixelIntensityRGB;

        for(int y = range.start; y < range.end; y++)
        {
            Vec3b *vDst = (Vec3b *)dst.ptr(y);
            for (int x = 0; x < imgSrc.cols; x++,vDst++) //for each pixel
            {
                pixelIntensityCount.assign(256,0);
                pixelIntensityRGB.assign(256,Vec3f(0,0,0));
                for(int yy = -radius; yy <= radius; yy++)
                {
                    Vec3b *vPtr = (Vec3b *)imgSrc.ptr(y+yy)+x-radius;
                    uchar *uc=intensityLUT.ptr(y+yy)+x-radius;
                    for(int xx = -radius; y + yy >= 0 && y+yy < imgSrc.rows && xx <= radius; xx++,vPtr++,uc++)
                    {
                        if( x+xx >= 0 && x+xx < imgSrc.cols)
                        {
                            int intensityVal = *uc;
                            pixelIntensityCount[intensityVal]++; // priority
                            pixelIntensityRGB[intensityVal] += *vPtr; //red

                        }
                    }
                }
                vector<int>::iterator it;
                int pos = distance(pixelIntensityCount.begin(),max_element(pixelIntensityCount.begin(),pixelIntensityCount.end()));
                *vDst = pixelIntensityRGB[pos]/pixelIntensityCount[pos];

            }
        }

    }
    ParallelInPaint& operator=(const ParallelInPaint &) {
         return *this;
    };
};


int main(int argc, char* argv[])
{
    VideoCapture v(0);
    Mat im;
    v>>im;
    Mat  intensityLUT(im.rows,im.cols,CV_8UC1);
    Mat  rgbLUT(im.rows,im.cols,CV_8UC3); //r/g/b
    Mat dst(im.rows,im.cols,CV_8UC3);
    int intensity = 20;
    int radius = 3;

    while (true)
    {

        v>>im;


        cvtColor(im,intensityLUT,CV_RGB2GRAY);
        intensityLUT = intensityLUT *(intensity/255.);

        ParallelInPaint x(im,dst,intensityLUT,radius);
        parallel_for_(Range(0,im.rows), x,getNumThreads());
        imshow("Result", dst);
        char c= waitKey(1);
        switch (c){
        case 'I':
            intensity++;
            if (intensity>255)
                intensity=255;
            break;
        case 'i':
            intensity--;
            if (intensity==0)
                intensity=1;
        case 'R':
            radius++;
            if (radius>255)
                radius=255;
            break;
        case 'r':
            radius--;
            if (radius==-1)
                radius=0;
        }
        if (c>32)
            cout << "Intensity =" << intensity << "\tradius = " << radius << "\n";
    }
    return 0;
}

You should use opencv function for color conversion. There is no opimization and it is not vey fast... (Check conversion int to float)

int main(int argc, char* argv[])
{
    Mat im=imread("Forest.jpg");
    Mat dst(im.rows,im.cols,CV_8UC3);

    Mat  intensityLUT(im.rows,im.cols,CV_8UC1);
    Mat  rgbLUT(im.rows,im.cols,CV_8UC3); //r/g/b
    int intensity = 20;
    int radius = 3;
    int pixelIntensityValue[100];
    Vec3f pixelIntensityRGB[100];

    cvtColor(im,intensityLUT,CV_RGB2GRAY);
    intensityLUT = intensityLUT *(intensity/255.);


    for(int y = 0; y < im.rows; y++)
    {
        for (int x = 0; x < im.cols; x++) //for each pixel
        {
            vector<int> pixelIntensityCount;
            vector<Vec3f> pixelIntensityRGB;
            pixelIntensityCount.assign(100,0);
            pixelIntensityRGB.assign(100,Vec3f(0,0,0));
            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.at<uchar>(y+yy,x+xx);
                        pixelIntensityCount[intensityVal]++; // priority
                        pixelIntensityRGB[intensityVal] += im.at<Vec3b>(y+yy,x+xx); //red

                    }
                }
            }
            vector<int>::iterator it;
            int pos = distance(pixelIntensityCount.begin(),max_element(pixelIntensityCount.begin(),pixelIntensityCount.end()));
            Vec3b v(pixelIntensityRGB[pos][0] / pixelIntensityCount[pos],pixelIntensityRGB[pos][1] / pixelIntensityCount[pos],pixelIntensityRGB[pos][2] / pixelIntensityCount[pos]);
            dst.at<Vec3b>(y, x) = v;

        }
    }
    imshow("Original", im);
    imshow("Result", dst);
    waitKey();
    return 0;
}