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

Popular posts from this blog

Getting started with OpenCV

Picking Apart Colours