Number of factors

Lets discuss another problem on codechef of medium difficulty NUMFACT

The problem says you are given n numbers and you have to return the total number of factors of the product of given n numbers.

So the problem consists of two problems:

  1. Given a number return all the prime factors. If prime factors are known other factors can be calculated.
  2. Given all prime factors of n numbers, return count of factors of the products of those n number.

Lets first solve 2nd problem

Lets assume we are given 2 numbers 6 and 10, so we need to return count of factors of 10*6 =>60.

6 => 2*3

10=> 2*5

60=> 22*31*51

factors of 60 are:

1(203050), 2(213050), 3(203150), 5(203051), 4(223050), 6(213150), 10(213051), 12(223150), 15(203151), 20(223051), 30(213151), 60(223151)

Now you might have guessed the result. To get the factors of a number we have to choose the coefficient of the prime factors. In case of 1, we chose to not choose any factor, in case of 12, we chose to choose 2 twice and 3 once and not choose 5.

So in how many ways we can do this choosing stuff is the total number of factors. We can do choosing in “product of all factors coefficient’s next number” ways. So for the above example (2+1)(1+1)(1+1)=>(3)(2)(2)=>12 ways

Now lets shift to the first problem. How to determine number of prime factors of a number along with its coefficients.

Since the number given can’t be more than 1000000, we know that it’s factor can be more that 10000001/2 => 1000. That means we just need to check whether numbers less than or equal to 1000 are factors of given number are not. In fact we should just check for prime factors less than or equal to 1000.

To compute prime numbers less than 1000.

  1. one simple approach would be that for each number(lets say x) less than 1000, start with 2 and check and go till x1/2 and see whether this number divides that number or not. If we get any number till x1/2 which divides x then x is not prime, if we don’t get any number then x is a prime.
  2. A better approach would be to create an array of 1000 elements(lets name isPrime) all element initialized to true, then start with i =2 and change all its multiple to false. Again start with i=3 and change all its multiple to false, again start with i=4 but since i=4 is already false don’t do any thing for this i and so on….

 

Mixtures

Today lets discuss about another problem named Mixtures.

The problem maps to the below problem:

You are given an array of n numbers and you are allowed to add any two adjacent numbers at a time, such that the result produced is sum of the two added elements mod 100, and the cost of doing the addition is product of the two added elements. You are required to give the combination such that cost is minimized.

Solution: If we think about the problem it looks like a math problem which says you are given a1a2….an-1an and you need to add them together such that addition result is ai+aj/100 and cost is ai*aj, and you are told to return the combination with minimum cost.

Can it be done in O(N)?

I don’t know. But lets first go naive. Lets first discuss in how many ways the mixing/addition can be done. After little bit of thinking the problem maps to permutation/combination problem.

You can choose your first element out of n elements in n ways, and after choosing first element the next element you want to mix it with can be chosen in 2 ways since the two added element should be adjacent. After the process you will be remained with n-1 elements, again going with similar logic the process can be done in 2*(n -1) steps and so on till the array remains with one element. So the entire process with take 2*n + 2*(n-1) + ….. + 2*1 steps => n*(n-1) steps.

Now if you see the limit of n in the problem, it says n can go till 100. That means any algorithm till O(N3) is okay for us.

The Next Palindrome

Lets look into another problem of codechef of Medium difficulty. The next palindrome

The problem is you are given a number and you need to return a palindrome just greater than that number. As you all know palindrome number is a number whose reversal(from end to start) is the same number. 121, 1331, 25452 are some examples of palindrome numbers.

So if you are given a number say 120 and you need to give a palindrome just bigger than that number, you now know the answer, it is 121.

But now the question is how to pro grammatically gets the answer. So lets try out.

lets say our given number k is a1a2a3a4a5…..an-1an, now since a1 is the most significant bit we would try to avoid changing it as much as possible but we can change an since it is least significant bit.

so for cases where a1a2a3..an..an-1an < a1a2a3…an/2..a2a1, a1a2a3..an/2..a2a1 is the palindrome. eg. 135 214 < 135 531 so for k = 135 214, 135 531 is the required palindrome.

But for cases where  a1a2a3..an..an-1an > a1a2a3…an/2..a2a1, a1a2a3..an/2..a2a1 is not the required palindrome because it is lesser. Lets divide the number in two halves..

135867 => 135    867

we can change 7 to 1 and 6 to 3 => 135 831 and change 5 and 8 to 6. => 136 631

but what if 5 was 9 and also 8 was 9 139967 => 139 967

we can change 7 to 1 and 6 to 3 => 139 931, now since 139931 < 139967 we need to change 9 to 10 reflecting the similar effect in other 9 of second half

13(10) 967  => 140 967 =do mirror imaging=>140 041

so for even digit numbers algo goes like this,

if an/2 < an/2+1

then increment an/2 to an/2+1 and forward the carry if there is any.

end if

do mirror imaging  of a1a2..an/2 to an/2+1…an-1an

Now for odd digit numbers algo goes like this,

if an-1/2 < an+1/2 +1

then increment an+1/2 by 1 and forward the carry if there is any.

end if

do mirror imaging  of a1a2..an-1/2 to an+1/2+1…an-1an

// thenextpalindrome.cpp : Defines the entry point for the console application.
//
#include <iostream>
using namespace std;

#include<stdio.h>
#include<string.h>
#define S(a,x) scanf("%"#a,&x) //#a expands to "a" we use this bcoz, arguments are not replaced within quoted strings
#define PS(a,x) printf("%"#a" ",x) //print with space
#define PN(a,x) printf("%"#a"\n",x) //print with newline
#define FOR(i,a,b) for( i=a;i<b;i++)
#define FORD(i,a,b) for( i=a;i>=b;i--)
#define REP(i,n) FOR(i,0,n)
#define Max(a, b) ((a>b)?a:b)
#define Min(a, b) ((a>b)?b:a)
#define MAXSIZE 1000001

int main()
{
int n,i, flag;
bool flag9 = true; // true if all 9s
char s[MAXSIZE];
S(d, n);
while (n--)
{
flag = 0; flag9 = true;
S(s, s);
// case 999999..
int len = strlen(s);
FOR(i, 0, len)
{
if (s[i] != '9')
{
flag9 = false;
break;
}
}
if (flag9)
{
cout << "1";
FOR(i, 0, len-1) cout << "0";
cout <<"1"<< endl;
}
else
{
FOR(i, 0, len/2)
{
if (s[i] < s[len - 1 - i])
{
flag = -1;
}
else if (s[i]>s[len - 1 - i])
{
flag = 1;
}
s[len - 1 - i] = s[i];
}
if (flag == 0 || flag == -1)
{
int current = (len - 1) / 2;
while (s[current] == '9')
{
s[current] = '0';
s[len - 1 - current] = s[current];
current--;
}
s[current]++;
s[len - 1 - current] = s[current];
}
PN(s, s);
}
}
return 0;
}

It sometimes gets very irritating when you get so many wrong answers and you are committed to solving the problem without seeing other’s solutions. Even if you see other’s solution you sometimes are not able to figure out what mistake you have done because of which your solution is not getting accepted. Basically you are striving for the testcases which are not passing in your case. Next time we will try to see how to find out those test cases programmatically.

We will write an algo which uses two solution files (one written by you which is not getting accepted and the other written by someone else and is getting accepted) and it runs both the files to find the conflicting tests.

Closing the tweets

Lets begin by solving one moderate level programming question on codechef. Please go through the question once.

Now if you have gone through the question, it basically maps to a problem that says there is an array sort of thing which is of type bool (initialized with false) and the user has the option to toggle it on/off and also there is one button to set all to false. Now with each attempt of user doing his input job you have to say how many bools are on/true in the array.

HINT: since the array is just 1000 size long even any algo of time complexity N is also fine.

Read the size of array vs time complexity relation here

Copying here just for your reference.

  • when N <= 10, then both O(N!) and O(2N) are ok (for 2N probably N <= 20 is ok too)
  • when N <= 100, then O(N3) is ok (I guess that N4 is also ok, but never tried)
  • when N <= 1.000, then N2 is also ok
  • when N <= 1.000.000, then O(N) is fine (I guess that 10.000.000 is fine too, but I never tried in contest)
  • finally when N = 1.000.000.000 then O(N) is NOT ok, you have to find something better…

SOLUTION:

Since it is clear that any algo with O(N2) complexity with work here.

What we will do is on every entry we will update the array which in case of click x will take o(1) time since x index can be reached in constant time, where as operation close all will take o(n) since we need to go to every index of array to update the element. After each entry we will also update our currentActive variable which stores the number of true bools of array.

So in worst case it will take  O(N2) time where each entry is closeall.

CODE:

// closethetweets.cpp : Defines the entry point for the console application.
//

#include
#include
using namespace std;

#include
#include
#define S(a,x) scanf("%"#a,&x) //#a expands to "a" we use this bcoz, arguments are not replaced within quoted strings
#define PS(a,x) printf("%"#a" ",x) //print with space
#define PN(a,x) printf("%"#a"\n",x) //print with newline
#define FOR(i,a,b) for( i=a;i<b;i++) #define FORD(i,a,b) for( i=a;i>=b;i--)
#define REP(i,n) FOR(i,0,n)
#define Max(a, b) ((a>b)?a:b)
#define Min(a, b) ((a>b)?b:a)
#define MAXSIZE 1010

int main()
{
int n, k, num;
int currentActive = 0;
bool arr[MAXSIZE] = { 0 };
S(d, n);
S(d, k);
char s[15];

while (k--)
{
S(s, s);
if (!strcmp(s, "CLICK"))
{
S(d, num);
num--; //0 based index
arr[num] = !arr[num]; //toggle
if (arr[num])
currentActive++;
else
currentActive--;
}
else
{
currentActive = 0;
memset(arr, 0, n + 1);
}
PN(d, currentActive);
}
return 0;
}

Lets begin problem solving

In this section and onwards I am going to explain and step by step solve some problems related to algorithms which will be very helpful if someone wants to sit in IT company interviews and/or want to compete in programming contest.

REQUIREMENT: you should have basic understanding of C/C++ as well as moderate understanding of data structures. Remembers this is not going to be a basic course. You should be decent in programming to go forward with this tutorial.

Adding Trackbar

Trackbar helps the user to play with image property dynamically, when your app is running. You can change brightness, contrast with the use of trackbar on the go.

#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/core.hpp"

using namespace cv;
#include <iostream>

using namespace std;

int main()
{
Mat img = imread("scenary2.png", CV_LOAD_IMAGE_COLOR);

int brightValue = 50;
int contrastValue = 50;
namedWindow("Image", CV_WINDOW_AUTOSIZE);

createTrackbar("brightness", "Image", &brightValue, 100);
createTrackbar("contrast", "Image", &contrastValue, 100);

while (1)
{
Mat dest;
double brightVal = brightValue - 50;
double contrastVal = contrastValue / 50.0;

img.convertTo(dest, -1, contrastVal, brightVal);

imshow("Image", dest);

if (waitKey(30) == 27)
{
break;
}
}

return 0;
}

Just run the application and play with the trackbars 😉

  • int createTrackbar(const string& trackbarname, const string& winname, int* value, int count, TrackbarCallback onChange = 0, void* userdata = 0)
This OpenCV function creates a trackbar and attached that trackbar to a specified window
    • trackbarname – The name of the trackbar
    • winname – The name of the window to which the trackbar is attached
    • value – This integer, pointed by this pointer, holds the value associated with the position of the trackbar
    • count – The maximum value of the trackbar. The minimum value is always zero.
    • onChange – This function will be called everytime the position of the trackbar is changed. The prototype of this function should be “FunctionName(int, void*)“. The “int” value is the value associate with the position of the trackbar. And “void*” is any pointer value which you pass as the “userdata” (See the next parameter).
    • userdata – This pointer variable will be passed as the second parameter of the above function

 

Now lets use the 5th and 6th parameter of the createTrackBar function to avoid running in infinite loop.

#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/core.hpp"

using namespace cv;
#include <iostream>
using namespace std;

Mat img;

void CallBackBrightNess(int brightVal, void* userData)
{
Mat src;
int cvalue = *(static_cast<int*>(userData));
double cFactor = (double)cvalue / 50.0;
img.convertTo(src, -1, cFactor, brightVal - 50);
imshow("Image", src);
}

void CallBackContrast(int contrastVal, void* userData)
{
Mat src;
double cFactor = (double)contrastVal / 50.0;
img.convertTo(src, -1, contrastVal / 50.0, *(static_cast<int*>(userData)) - 50);
imshow("Image", src);
}

int main()
{
img = imread("scenary2.png", CV_LOAD_IMAGE_COLOR);

int brightValue = 50;
int contrastValue = 50;
namedWindow("Image", CV_WINDOW_AUTOSIZE);

createTrackbar("brightness", "Image", &brightValue, 100, CallBackBrightNess, &contrastValue);
createTrackbar("contrast", "Image", &contrastValue, 100, CallBackContrast, &brightValue);

imshow("Image", img);

waitKey(0);

return 0;
}

OpenCV: playing with brightness, contrast, histogram, blurness

Change Brightness of Image or Video

Changing brightness is a point operation on each pixel. If you want to increase the brightness, you have to add some constant value to each and every pixel.
new_img (i, j) = img(i, j) + cIf you want to decrease the brightness, you have to subtract some constant value from each and every pixel.
new_img (i, j) = img(i, j) – ce.g- Say, this is your original image

Original Image
Original Image

Say, you want to increase the brightness of the image by 20 units. Here is the output image of which the  brightness is increased by 20 units.

Image of which brightness is increased
Image of which brightness is increased

Say, you want to decrease the brightness of the image by 20 units. Here is the output image of which the  brightness is decreased by 20 units.

Image of which brightness is decreased
Image of which brightness is decreased

Note :
You may already notice that although the 1st pixel of the above image should have (12 – 20)  = -8, I have put 0. It is because pixels never have negative values. Any pixel value is bounded below by 0 and bounded above by 2^(bit depth).

#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/core.hpp"using namespace cv;
#include <iostream>using namespace std;

int main()
{
Mat img = imread("Deepika_Padukone.jpg");
Mat imgH;
Mat imgL;
imgH = img + Scalar(100, 100, 100);
imgL = img + Scalar(-100, -100, -100);

namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
namedWindow("Increased Brightness Image", CV_WINDOW_AUTOSIZE);
namedWindow("Decreased Brightness Image", CV_WINDOW_AUTOSIZE);

imshow("Original Image", img);
imshow("Increased Brightness Image", imgH);
imshow("Decreased Brightness Image", imgL);
cvWaitKey(0);

return 0;
}

Change Contrast of Image or Video

Changing the contrast is also a point operation on each pixel. The easiest way to increase the contrast of an image is, multiplying each pixel value by a number larger than 1.
                         new_img (i, j) = img(i, j) * c                     c > 1
The easiest way to decrease the contrast is, multiplying each pixel value by a number smaller than 1.
                         new_img (i, j) = img(i, j) * c                     c < 1
There are more advance methods to adjust contrast of an image such as histogram equalization. Such method adjust the contrast of an image such that color distribution is balanced equally. We will discuss the histogram equalization in the next lesson.
e.g- Say, this is your original image
Example Image
Example Image
By multiplying each pixel value by 2, you can effectively double the contrast of an image. Here is the image of which the contrast is increased.
I have considered this image as a 8 bit unsigned image. So, any pixel value should be from 0 to 255. If the resulting image has values more than 255, it should be rounded off to 255.
Contrast Increased
Contrast Increased
By multiplying each pixel value by 0.5, you can effectively halve the contrast of an image. Here is the image of which contrast is decreased.
Contrast Decreased
Contrast Decreased
#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/core.hpp"

using namespace cv;
#include <iostream>

using namespace std;

int main()
{
Mat img = imread("Deepika_Padukone.jpg");
Mat imgH;
Mat imgL;
imgH = img * 1.2;
imgL = img *0.8;

namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
namedWindow("Increased contrast Image", CV_WINDOW_AUTOSIZE);
namedWindow("Decreased contrast Image", CV_WINDOW_AUTOSIZE);

imshow("Original Image", img);
imshow("Increased contrast Image", imgH);
imshow("Decreased contrast Image", imgL);
cvWaitKey(0);
return 0;
}

Instead of imgH = img * 1.2, you can use convertTo function.

img.convertTo(imgH, -1, 1.2, 0); //increase the contrast (double)

 

  • void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 )
This OpenCV function converts  image into another format with scaling. Scaling is done according to the following formula.
                                              m[i,j] = alfa * img[i,j] + beta
Here is the parameters of this function
    • OutputArray m – Store the converted image
    • int rtype – Depth of the output image. If the value of rtype is negative, output type is same as the input image. I have used a negative value in the above program because I don’t want to change the depth of the original image. Possible inputs to this parameter
      • CV_8U
      • CV_32S
      • CV_64F
      • -1
    • double alpha – Multiplication factor; Every pixel will be multiplied by this value
    • double beta – This value will be added to very pixels after multiplying with the above value.
Here is the formula again. Here m[i, j] means a pixel at ith row and jth column.
m[i,j] = alfa * img[i,j] + beta

Histogram Equalization of Grayscale or Color Image

Histogram

Histogram is the intensity distribution of an image.
E.G –
Consider the following image. Say, depth of the image is 2 bits. Therefore the value range for each and every pixel is from 0 to 3.
Sample Image (Depth = 2 bits)
Sample Image (Depth = 2 bits)
Histogram of the a image shows how the pixel values are distributed. As you can see in the above image there are 5 pixels with value 0, 7 pixels with value 1, 9 pixels with value 2 and 4 pixels with value 3. These information is tabulated as follows.
Intensity Distribution of above image
Intensity Distribution of above image
Histogram of a image usually presented as a graph. The following graph represents the histogram of the above image.
Image Histogram
Image Histogram

Histogram Equalization

Histogram Equalization is defined as equalizing the intensity distribution of an image or flattening the intensity distribution curve. Histogram equalization is used to improve the contrast of an image. The equalized histogram of the above image should be ideally like the following graph.
Equalized Histogram
Equalized Histogram
But practically, you cannot achieve this kind of perfect histogram equalization. But there are various techniques to achieve histogram equalization close to the perfect one. In OpenCV, there is an in-built OpenCV function to equalize histogram.
With uncolored image
#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/core.hpp"using namespace cv;
#include <iostream>using namespace std;

int main()
{
Mat img = imread("Deepika_Padukone.jpg");
cvtColor(img, img, CV_BGR2GRAY);
Mat imgHist;
equalizeHist(img, imgHist);

namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
namedWindow("Histogram Image", CV_WINDOW_AUTOSIZE);

imshow("Original Image", img);
imshow("Histogram Image", imgHist);
cvWaitKey(0);

return 0;
}


With colored image
#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/core.hpp"using namespace cv;
#include <iostream>

using namespace std;

int main()
{
Mat img = imread("scenary2.png", CV_LOAD_IMAGE_COLOR);

Mat imgHist, Y, Cr, Cb;
vector<Mat> channels(3);
cvtColor(img, imgHist, CV_BGR2YCrCb);

split(img, channels);

equalizeHist(channels[0], channels[0]);

merge(channels, imgHist);
namedWindow("Histogram before convert Image", CV_WINDOW_AUTOSIZE);

imshow("Histogram before convert Image", imgHist);

cvtColor(imgHist, imgHist, CV_YCrCb2BGR);

namedWindow("Original Image", CV_WINDOW_AUTOSIZE);
namedWindow("Histogram Image", CV_WINDOW_AUTOSIZE);

imshow("Original Image", img);
imshow("Histogram Image", imgHist);
cvWaitKey(0);

return 0;
}

Some of the functions to look:

  • cvtColor(img, img_hist_equalized, CV_BGR2YCrCb)
This line converts the color space of BGR in ‘img‘ to YCrCb color space and stores the resulting image in ‘img_hist_equalized‘.
In the above example, I am going to equalize the histogram of color images. In this scenario, I have to equalize the histogram of the intensity component only, not the color components. So, BGR format cannot be used because its all three planes represent color components blue, green and red. So, I have to convert the original BGR color space to YCrCb color space because its 1st plane represents the intensity of the image where as other planes represent the color components.
  • void split(const Mat& m, vector<Mat>& mv )
This function splits each channel of the ‘m‘ multi-channel array into separate channels and stores them in a vector, referenced by ‘mv‘.
Argument list
    • const Mat& m – Input multi-channel array
    •  vector<Mat>& mv – vector that stores the each channel of the input array
  • equalizeHist(channels[0], channels[0]);
Here we are only interested in the 1st channel (Y) because it  represents the intensity information whereas other two channels (Cr and Cb) represent color components. So, we equalize the histogram of the 1st channel using OpenCV in-built function, ‘equalizeHist(..)’ and other two channels remain unchanged.
  • void merge(const vector<Mat>& mv, OutputArray dst )
This function does the reverse operation of the split function. It takes the vector of channels and create a single multi-channel array.
Argument list
    • const vector<Mat>& mv – vector that holds several channels. All channels should have same size and same depths
    • OutputArray dst – stores the destination multi-channel array
  • cvtColor(img_hist_equalized, img_hist_equalized, CV_YCrCb2BGR)
This line converts the image from YCrCb color space to BGR color space. It is essential to convert to BGR color space because ‘imshow(..)’ OpenCV function can only show images with that color space.

Filtering image: dilation, inversion, erosion

#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/core.hpp"

using namespace cv;
#include <iostream>

using namespace std;

int main()
{
//display the original image
IplImage* img = cvLoadImage("Deepika_Padukone.jpg");
cvNamedWindow("MyWindow");
cvShowImage("MyWindow", img);
while (1)
{

IplImage* img2 = img;
int ans = waitKey(30);
if (ans == 65)
{
//erode and display the eroded image
cvErode(img, img2, 0, 2);
cvNamedWindow("Eroded");
cvShowImage("Eroded", img2);
}
else if (ans == 66)
{
//dilate and display the eroded image
cvDilate(img, img2, 0, 2);
cvNamedWindow("dilated");
cvShowImage("dilated", img2);
}
else if (ans == 67)
{
//invert and display the eroded image
cvNot(img, img2);
cvNamedWindow("inverted");
cvShowImage("inverted", img2);
}

}
cvWaitKey(0);

//cleaning up
cvDestroyWindow("MyWindow");
cvDestroyWindow("Eroded");
cvReleaseImage(&img);

return 0;
}

Press A, B, C and see the magic 😉

Writing Image and Video to file

Writing image got from camera

Following program saves the image when you press ‘A’ from your keyboard.

#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/core.hpp"

using namespace cv;
#include <iostream>

using namespace cv;
using namespace std;

int main( int argc, const char** argv )
{
VideoCapture cap(0); // opens the video camera 0

if (!cap.isOpened()) // if not success, exit program
{
cout << "Cannot open the video file" << endl;
return -1;
}

double frame = cap.get(CAP_PROP_POS_FRAMES);

//playing with other arguments of namedWindow to see the effect.

namedWindow("myVideo", CV_WINDOW_NORMAL);

while (1)
{
Mat frame;
if (cap.read(frame))
{
imshow("myVideo", frame);
}
else
{
cout << "error reading frames \n";
}

if (waitKey(30) == 65)
{
vector<int> compression_params; //vector that stores the compression parameters of the image

compression_params.push_back(CV_IMWRITE_JPEG_QUALITY); //specify the compression technique

compression_params.push_back(98); //specify the compression quality

bool bSuccess = imwrite("D:/TestImage.jpg", frame, compression_params); //write the image to file
if (!bSuccess)

{

cout << "ERROR : Failed to save the image" << endl;

//system("pause"); //wait for a key press

}
break;
}
}
return 0;
}

Remember saving the image to drive other than C:, usually saving to C: Drive causes permission issue.

Writing video got from camera

#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/core/core.hpp"

using namespace cv;
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, const char** argv)
{
VideoCapture cap(0); // opens the video camera 0

if (!cap.isOpened()) // if not success, exit program
{
cout << "Cannot open the video file" << endl;
return -1;
}

double frame = cap.get(CAP_PROP_POS_FRAMES);

namedWindow("MyVideo", CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"

double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video

cout << "Frame Size = " << dWidth << "x" << dHeight << endl;

Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));

VideoWriter oVideoWriter("D:/MyVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 20, frameSize, true); //initialize the VideoWriter object
//20 is frame rate..

if (!oVideoWriter.isOpened()) //if not initialize the VideoWriter successfully, exit the program
{
cout << "ERROR: Failed to write the video" << endl;
return -1;
}

while (1)
{
Mat frame;
bool success = cap.read(frame);

if (success)
{
oVideoWriter.write(frame);
imshow("MyVideo", frame);
}
if (waitKey(10) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}

return 0;
}