1 | initial version |
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;
}
2 | No.2 Revision |
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;
}