Adding Noise To An Image With OpenCV
As a fun little project, let's try and add a little noise to an image. In particular, let's try adding something called salt-and-pepper noise to an image. So what is salt and pepper noise?Basically, we take an image, select a random pixel and convert it to a black or white pixel. For example, the white grainy image shown to the right is a "noisy" version of the one above it. So, how did I do this?
First, I took the dimensions of the sample image that I wished to
process. Then, we can think of the entire image as a 2-D array and
each pixel can be located using $(i,j)$, where $i$ = position along the
row and $j$ = position along the column. For example, the third pixel
from the left, two rows down, would be $(2,1)$. Great! Now we have a
system for pointing to a particular pixel in the image. So how do we
take a random pixel? Here’s the interesting thing. Suppose you take
a constant $a$ and a variable number $b$. Then, suppose we
did $b$%$a$($b$ modulo $a$). What do we get? You see, interestingly
enough, irregardless of what ‘b’ is, the range of $b$%$a$ is
such that:- $1<b$%$a<a$.
Aha! Do you see it!? Essentially, what we worked out above allows us to easily select a
random pixel on the image while constraining the position of the pixel
within the range of the image’s dimensions. Of course, after this,
the code is essentially self explanatory. Once we have the location of the pixel, we convert the pixel's colour to white by setting all the RGB values to 255.
#include <iostream>
#include <highgui.h>
using namespace std;
using namespace cv;
void proc(Mat &a,int b);
int main(int argc, char** argv)
{
char getc[10];
int num;
cout<<"Please the name of you image file: ";
cin.getline(getc,10);
Mat img_in = imread(getc,CV_LOAD_IMAGE_ANYCOLOR);
if(img_in.empty())
{
cout<<"There is no valid image to be read"<<endl;
cin>>num;
proc(img_in,num);
}
}
void proc(Mat &input,int n)
{
for(unsigned int i = 0;i<n;i++)
{
int a =rand()%input.cols;
int b =rand()%input.rows;
if(input.channels() == 1)
{
input.at<uchar>(b,a) = 255;
}
else if(input.channels() == 3)
{
input.at<Vec3b>(b,a)[0] = 255;
input.at<Vec3b>(b,a)[1] = 255;
input.at<Vec3b>(b,a)[2] = 255;
}
}
namedWindow("Output",CV_WINDOW_KEEPRATIO);
imshow("Output",input);
waitKey(0);
destroyAllWindows();
}
Comments
Post a Comment