piątek, 11 kwietnia 2014

OpenCV HOWTO: capture camera and do linear transformation on image

In this tutorial I'll try to show you how to do magic with OpenCV. I hope you've already installed it. We'll need some standard namespaces:

using namespace cv;
using namespace std;
view raw cv usings hosted with ❤ by GitHub
First, we have to create some Mat objects in which we'll store our images:
Mat_<Vec3b> image;
Mat grayImage;
Mat negativeImage(480, 640, CV_8UC1);
Mat_<Vec3b> colorNegativeImage(480, 640, CV_16U);
Mat_<Vec3b> manipulatedImage(480, 640, CV_16U);
view raw mats hosted with ❤ by GitHub
And variables to store linear transformation values:
int value;
double plus = 0.0, mult = 1.0;
view raw values hosted with ❤ by GitHub
Then we intialize capturing camera image:
VideoCapture cap(0); // 0 for notebook camera, 1 for external camera
if(!cap.isOpened())
{
cout << "Camera error";
return -1;
}
cap.open(0);
view raw camera capture hosted with ❤ by GitHub
And open windows to show results:
namedWindow("window", CV_WINDOW_AUTOSIZE);
namedWindow("grayWindow", CV_WINDOW_AUTOSIZE);
namedWindow("negativeGrayWindow", CV_WINDOW_AUTOSIZE);
namedWindow("negativeColorWindow", CV_WINDOW_AUTOSIZE);
namedWindow("linearWindow", CV_WINDOW_AUTOSIZE);
view raw open windows hosted with ❤ by GitHub
Then we have to open infinite loop. In each iteration we have to capture the image from camera:
// original image
cap >> image;
view raw original image hosted with ❤ by GitHub
We can also make it gray:
// bw
cvtColor(image, grayImage, CV_BGR2GRAY);
view raw gray image hosted with ❤ by GitHub
If we want to get negative image, we have to subtract the image pixels values from 255 (because 255 is maximum value):
// bw negative
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++) {
negativeImage.at<uchar>(i,j) = 255 - grayImage.at<uchar>(i,j);
}
}
view raw bw negative hosted with ❤ by GitHub
If we want to get color negative image, we have to subtract the image pixels values in all dimensions (3) from 255:
// color negative
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++) {
for (int k = 0; k < 3; k++) {
colorNegativeImage.at<Vec3b>(i,j)[k] = 255 - image.at<Vec3b>(i,j)[k];
}
}
}
view raw color negative hosted with ❤ by GitHub
For linear transformation we have to calculate each dimension of each pixel. If we have to increase (decrease) contrast, we have to multiply source value by value grater than 1 (smaller than 1). Adding (subtracting) value to the source gives increased (decreased) brightness:
// image manipulation
for (int i = 0; i < image.rows; i++) {
for (int j = 0; j < image.cols; j++) {
for (int k = 0; k < 3; k++) {
value = image.at<Vec3b>(i,j)[k] * mult + plus;
if (value > 255) {
value = 255;
}
if (value < 0) {
value = 0;
}
manipulatedImage.at<Vec3b>(i,j)[k] = value;
}
}
}
Next we want to show our images:
imshow("window", image);
imshow("grayWindow", grayImage);
imshow("negativeGrayWindow", negativeImage);
imshow("negativeColorWindow", colorNegativeImage);
imshow("linearWindow", manipulatedImage);
view raw show windows hosted with ❤ by GitHub
At the end, we want to manipulate the values to linear transformation by pressing arrows or pressing ESC to leave the application.
int c = waitKey(20);
switch(c)
{
case 27: //ESC
destroyAllWindows();
return 0;
break;
case 2621440: //down
plus -= 20;
break;
case 2490368: //up
plus += 20;
break;
case 2555904: //right
mult += 0.1;
break;
case 2424832: //left
mult -= 0.1;
break;
case 32: //space, reset parameters
plus = 0;
mult = 1;
break;
default:
break;
}
view raw linear params hosted with ❤ by GitHub
That's all, hope you'll find it useful!