displaying updated video histogram with each fram - c++

I want to display updated histogram of each frame from a video file,
the video file is captured and then passed to histogram calculation function
I have made some changes to the following code .But it is not working as I want .
I appreciate any help
Regards
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
void histogramcalculation(const Mat &Image, Mat &histoImage)
{
int histSize = 255;
// Set the ranges ( for B,G,R) )
float range[] = { 0, 256 } ;
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
Mat b_hist, g_hist, r_hist;
// Compute the histograms:
calcHist( &Image, 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
// Draw the histogram
int hist_w = 512; int hist_h = 400;
int bin_w = cvRound( (double) hist_w/histSize );
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );
// Normalize the result to [ 0, histImage.rows ]
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
// Draw
for( int i = 1; i < histSize; i++ )
{
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float> (i-1)) ) , Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ), Scalar( 255, 0, 0), 2, 8, 0 );
}
histoImage= histImage;
}
int main( )
{
Mat histImage;
VideoCapture cap("eye.mp4"); // open video
if(!cap.isOpened()) // check if we succeeded
return -1;
namedWindow("Video",1);
namedWindow("ycbcr",1);
while(1)
{
Mat frame;
cap >> frame; // get a new frame
imshow( "video", frame );
// Calculate the histogram
histogramcalculation(frame, histImage);
// Display the histogram
imshow("Colour Image Histogram", histImage );
// Wait until user exits the program
waitKey();
}
return 0;
}

The below code will draw a histogram for grayScale image. If you want to draw a histogram for a color image, you have to split the image into separate channels and can these separate channels to draw histogram individually.
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
void histogramcalculation(const Mat &Image, Mat &histoImage)
{
int histSize = 255;
// Set the ranges ( for B,G,R) )
float range[] = { 0, 256 } ;
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
Mat b_hist, g_hist, r_hist;
// Compute the histograms:
calcHist( &Image, 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
// Draw the histogram
int hist_w = 512; int hist_h = 400;
int bin_w = cvRound( (double) hist_w/histSize );
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );
// Normalize the result to [ 0, histImage.rows ]
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
// Draw
for( int i = 1; i < histSize; i++ )
{
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float> (i-1)) ) , Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ), Scalar( 255, 0, 0), 2, 8, 0 );
}
histoImage= histImage;
}
int main( )
{
Mat histImage;
VideoCapture cap("test1.avi"); // open video
if(!cap.isOpened()) // check if we succeeded
return -1;
while(1)
{
Mat frame;
cap >> frame; // get a new frame
imshow( "video", frame );
cvtColor(frame, frame, CV_BGR2GRAY );
// Calculate the histogram
histogramcalculation(frame, histImage);
// Display the histogram
imshow("Gray Scale Image Histogram", histImage );
// Wait until user exits the program
waitKey(5);
}
return 0;
}

Related

Merging two 1d histograms into one

I got two histograms which I created with standard openCV function calcHist:
int getModels(string filename) {
Mat src = imread(filename, 1);
if(!src.data) { return -1; }
Mat imageHSV;
cvtColor(src, imageHSV, COLOR_BGR2HSV);
vector<Mat> bgr_planes;
split(imageHSV, bgr_planes);
int histSize = 256;
float range[] = { 0, 256 } ;
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
Mat g_hist, r_hist;
calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate );
calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );
cv::Mat combined_hist = g_hist + r_hist;
int hist_w = 512; int hist_h = 400;
int bin_w = cvRound( (double) hist_w/histSize );
Mat histImage(hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );
for( int i = 0; i < histSize; i++ )
{
line( histImage, Point( bin_w*(i-1), cvRound(combined_hist.at<float>(i-1)) ) ,
Point( bin_w*(i), cvRound(combined_hist.at<float>(i)) ),
Scalar( 19,90,87), 2, 8, 0 );
}
/// Display
namedWindow(filename, CV_WINDOW_AUTOSIZE );
imshow(filename, histImage );
return 0;
}
Is there any way to merge them into one combined_hist histogram?
Yes, you can. OpenCV has cv::add which can be used like this:
cv::Mat combined_hist;
cv::add(g_hist, r_hist, combined_hist);
However, since cv::Mat has overloaded operators, you can just do this:
cv::Mat combined_hist = g_hist + r_hist;
Hope that helps you.

calculating cumulative histogram

I want to calculate the cumulative histogram , I have done the histogram calculation and below is the code for it.
I have converted the iamge to ycbcr channel and applied histogram for Y channel
Thanks for help
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "iostream"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
void histogramcalculation(const Mat &Image, Mat &histoImage)
{
int histSize = 255;
// Set the ranges ( for B,G,R) )
float range[] = { 0, 256 } ;
const float* histRange = { range };
bool uniform = true; bool accumulate = false;
Mat b_hist, g_hist, r_hist;
vector<Mat> bgr_planes;
split(Image, bgr_planes );
// Compute the histograms:
calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate );
// Draw the histogram
int hist_w = 512; int hist_h = 400;
int bin_w = cvRound( (double) hist_w/histSize );
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );
// Normalize the result to [ 0, histImage.rows ]
normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
// Draw
for( int i = 1; i < histSize; i++ )
{
line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float> (i-1)) ) , Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ), Scalar( 255, 0, 0), 2, 8, 0 );
}
histoImage= histImage;
}
int main( )
{
Mat src, imageq,ycbcr;
Mat histImage;
// Read original image
src = imread( "3.jpg");
if(! src.data )
{ printf("Error imagen\n"); exit(1); }
cvtColor(src, ycbcr, CV_RGB2YCrCb);
vector <Mat> planes;
split(ycbcr,planes);
// Separate the image in 3 places ( B, G and R )
// Display results
imshow( "Source image", src );
// Calculate the histogram to each channel of the source image
histogramcalculation(planes[0], histImage);
// Display the histogram for each colour channel
imshow("Colour Image Histogram", histImage );
// Wait until user exits the program
waitKey();
return 0;
}
OpenCV cv::calcHist has the accumulate flag, but that doesn't do a cummulative histogram, it just doesn't set the histogram to zero at the beginning, so you can accumulate histograms over multiple images.
What you want to do, is after getting the histogram, just accumulate it yourself by adding the sum of all previous histogram bins to every bin.
cv::Mat hist;
cv::calcHist(&eyeROI, 1, 0, Mat(), hist, 1, &histSize, &histRange);
cv::Mat accumulatedHist = hist.clone();
for (int i = 1; i < histSize; i++) {
accumulatedHist.at<float>(i) += accumulatedHist.at<float>(i - 1);
std::cout << "Accumulated : " << accumulatedHist.at<float>(i) << ", original = " << hist.at<float>(i) << std::endl;
}
std::cout added so you can look at the result.

Hough algorithm don't find outer circle when there is a circle inside

I use hough transform to find circles in my picture, but it doesn't find outer circle.( I use opencv 2.4.2 and QT 3.3.0)
my code:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
int HoughCircle1()
{
Mat src,dst, src_gray;
/// Read the image
src = imread("E:/imagesForImgProc/test.jpg",CV_LOAD_IMAGE_COLOR);
if( !src.data )
{
return -1;
}
/// Reduce the size of image
Size size(src.cols/2,src.rows/2);
resize(src, dst,size, 0, 0, CV_INTER_LINEAR);
/// Convert it to gray
cvtColor( dst, src_gray, CV_BGR2GRAY );
/// Reduce the noise so we avoid false circle detection
GaussianBlur( src_gray, src_gray, Size(9, 9), 2, 2 );
/// Apply the Hough Transform to find the circles
vector<Vec3f> circles;
HoughCircles( src_gray, circles,CV_HOUGH_GRADIENT, 1, src_gray.rows/8, 200, 100, 0, 0 );
/// Draw the circles detected
for( size_t i = 0; i < circles.size(); i++ )
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
/// circle center
circle( dst, center, 3, Scalar(0,255,0), -1, 8, 0 );
/// circle outline
circle( dst, center, radius, Scalar(0,0,255), 1, 8, 0 );
}
/// Show your results
namedWindow( "Hough Circle Transform Demo", CV_WINDOW_AUTOSIZE );
imshow( "Hough Circle Transform Demo", dst );
return 0;
}
int main()
{
HoughCircle1();
waitKey(0);
return 0;
}
"Orginal image"
"Code result "
"Wanted result"

Dynamic OpenCV Histogram errors

I am using a variant the Histogram comparison code given by the OpenCV documentation to check the similarities of a submitted image to others stored in my filesystem. The problem is that the values I am getting are different from the original comparison that I used.
Original code:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
/** #function main */
int main( int argc, char** argv )
{
Mat src_base, hsv_base;
Mat src_test1, hsv_test1;
Mat src_test2, hsv_test2;
Mat hsv_half_down;
/// Load three images with different environment settings
if( argc < 4 )
{ printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_setting1> <image_settings2>\n");
return -1;
}
src_base = imread( argv[1], 1 );
src_test1 = imread( argv[2], 1 );
src_test2 = imread( argv[3], 1 );
/// Convert to HSV
cvtColor( src_base, hsv_base, CV_BGR2HSV );
cvtColor( src_test1, hsv_test1, CV_BGR2HSV );
cvtColor( src_test2, hsv_test2, CV_BGR2HSV );
hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );
/// Using 30 bins for hue and 32 for saturation
int h_bins = 50; int s_bins = 60;
int histSize[] = { h_bins, s_bins };
// hue varies from 0 to 256, saturation from 0 to 180
float h_ranges[] = { 0, 256 };
float s_ranges[] = { 0, 180 };
const float* ranges[] = { h_ranges, s_ranges };
// Use the o-th and 1-st channels
int channels[] = { 0, 1 };
/// Histograms
MatND hist_base;
MatND hist_half_down;
MatND hist_test1;
MatND hist_test2;
/// Calculate the histograms for the HSV images
calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false );
normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false );
normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false );
normalize( hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_test2, 1, channels, Mat(), hist_test2, 2, histSize, ranges, true, false );
normalize( hist_test2, hist_test2, 0, 1, NORM_MINMAX, -1, Mat() );
/// Apply the histogram comparison methods
for( int i = 0; i < 4; i++ )
{ int compare_method = i;
double base_base = compareHist( hist_base, hist_base, compare_method );
double base_half = compareHist( hist_base, hist_half_down, compare_method );
double base_test1 = compareHist( hist_base, hist_test1, compare_method );
double base_test2 = compareHist( hist_base, hist_test2, compare_method );
printf( " Method [%d] Perfect, Base-Half, Base-Test(1), Base-Test(2) : %f, %f, %f, %f \n", i, base_base, base_half , base_test1, base_test2 );
}
printf( "Done \n" );
return 0;
}
Heres how I have changed the code (I carry on from the second calcHist):
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
Mat src_base, hsv_base;
Mat hsv_half_down;
Mat src_rest, hsv_rest;
if( argc < 2 )
{
printf("** Error. Usage: ./compareHist_Demo <image_settings0> <image_setting1> <image_settings2>\n");
return -1;
}
src_base = imread( argv[1], 1 );
/// Convert to HSV
cvtColor( src_base, hsv_base, COLOR_BGR2HSV );
hsv_half_down = hsv_base( Range( hsv_base.rows/2, hsv_base.rows - 1 ), Range( 0, hsv_base.cols - 1 ) );
/// Using 30 bins for hue and 32 for saturation
int h_bins = 50; int s_bins = 60;
int histSize[] = { h_bins, s_bins };
// hue varies from 0 to 256, saturation from 0 to 180
float s_ranges[] = { 0, 256 };
float h_ranges[] = { 0, 180 };
const float* ranges[] = { h_ranges, s_ranges };
// Use the o-th and 1-st channels
int channels[] = { 0, 1 };
/// Histograms
MatND hist_base;
MatND hist_half_down;
MatND hist_rest;
/// Calculate the histograms for the HSV images
calcHist( &hsv_base, 1, channels, Mat(), hist_base, 2, histSize, ranges, true, false );
normalize( hist_base, hist_base, 0, 1, NORM_MINMAX, -1, Mat() );
calcHist( &hsv_half_down, 1, channels, Mat(), hist_half_down, 2, histSize, ranges, true, false );
normalize( hist_half_down, hist_half_down, 0, 1, NORM_MINMAX, -1, Mat() );
Mat src_rest, hsv_rest;
MatND hist_rest;
std::vector<string> src;
string line;
ifstream myfile ("/Users/Dave/Desktop/foods.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
src.push_back(line);
}
myfile.close();
}
else cout << "Unable to open file";
long arrLength = src.size();
for(int i = 0;i<arrLength;i++){
src_rest = imread(src[i],1);
cvtColor(src_rest, hsv_rest, COLOR_BGR2HSV);
calcHist(&hsv_rest, 1, channels, Mat(), hist_rest, 2, histSize, ranges, true, false);
normalize(hist_rest, hist_rest, 0, 1, NORM_MINMAX, -1, Mat());
double baseComp = compareHist( hist_rest, hist_base, 0 );
cout<<"Main picture compared to "<<src[i]<<" using correlation "<<baseComp<<'\n';
}
printf("\n");
for(int i = 0;i<arrLength;i++){
src_rest = imread(src[i],1);
cvtColor(src_rest, hsv_rest, COLOR_BGR2HSV);
calcHist(&hsv_rest, 1, channels, Mat(), hist_rest, 2, histSize, ranges, true, false);
normalize(hist_rest, hist_rest, 0, 1, NORM_MINMAX, -1, Mat());
double baseComp = compareHist( hist_rest, hist_base, 1 );
cout<<"Main picture compared to "<<src[i]<<" using chi values "<<baseComp<<'\n';
}
for(int i = 0;i<arrLength;i++){
src_rest = imread(src[i],1);
cvtColor(src_rest, hsv_rest, COLOR_BGR2HSV);
calcHist(&hsv_rest, 1, channels, Mat(), hist_rest, 2, histSize, ranges, true, false);
normalize(hist_rest, hist_rest, 0, 1, NORM_MINMAX, -1, Mat());
double baseComp = compareHist( hist_rest, hist_base, 2 );
cout<<"Main picture compared to "<<src[i]<<" intersection "<<baseComp<<'\n';
}
for(int i = 0;i<arrLength;i++){
src_rest = imread(src[i],1);
cvtColor(src_rest, hsv_rest, COLOR_BGR2HSV);
calcHist(&hsv_rest, 1, channels, Mat(), hist_rest, 2, histSize, ranges, true, false);
normalize(hist_rest, hist_rest, 0, 1, NORM_MINMAX, -1, Mat());
double baseComp = compareHist( hist_base, hist_rest, 3 );
cout<<"Main picture compared to "<<src[i]<<" bhattacharyya "<<baseComp<<'\n';
}
The rest of code that has been omitted is the rest of the initialisation in the OpenCV version.
Heres the original output:
Method [0] Perfect, Base-Half, Base-Test(1), Base-Test(2) : 1.000000, 0.999990, 0.979741, 0.952336
Method [1] Perfect, Base-Half, Base-Test(1), Base-Test(2) : 0.000000, 0.018286, 128.338021, 130.609857
Method [2] Perfect, Base-Half, Base-Test(1), Base-Test(2) : 1.260779, 1.225753, 1.225654, 1.254846
Method [3] Perfect, Base-Half, Base-Test(1), Base-Test(2) : 0.000000, 0.052663, 0.440655, 0.494793
And heres my output:
Main picture compared to base.jpg using correlation 1
Main picture compared to test1.jpg using correlation 0.763895
Main picture compared to test2.jpg using correlation 0.54124
Main picture compared to base.jpg using chi values 0
Main picture compared to test1.jpg using chi values 223.443
Main picture compared to test2.jpg using chi values 876.137
Main picture compared to base.jpg intersection 3.4481
Main picture compared to test1.jpg intersection 1.78523
Main picture compared to test2.jpg intersection 1.79021
Main picture compared to base.jpg bhattacharyya 1.05367e-08
Main picture compared to test1.jpg bhattacharyya 0.569303
Main picture compared to test2.jpg bhattacharyya 0.675118
So is there an issue with the way I have laid out the code in loops for me to get completely different results?

Histogram for green component of an image in c++ using OpenCV

I want to create a histogram for an green component of an image in c++ using OpenCV.
The following code is working fine for color image but once i split the image into its RGB component and using the green component to call calcHist function, I am getting the following error.
OpenCV Error: Assertion failed (j < nimages) in histPrepareImages, file /root/src/OpenCV-2.4.1/modules/imgproc/src/histogram.cpp, line 148
terminate called after throwing an instance of 'cv::Exception'
what(): /root/src/OpenCV-2.4.1/modules/imgproc/src/histogram.cpp:148: error: (-215) j < nimages in function histPrepareImages
Aborted (core dumped)
Here is my code for the same.
I took two images to create the histogram. Anyone pls help so solve this problem.
#include <cv.h>
#include <highgui.h>
using namespace cv;
int main( int argc, char** argv )
{
Mat src,src1, hsv, hsv1;
if( argc != 3 || !(src=imread(argv[1], 1)).data || !(src=imread(argv[2], 1)).data)
return -1;
std::vector<cv::Mat> three_channels;
cv::split(src,three_channels);
std::vector<cv::Mat> three_channels1;
cv::split(src1,three_channels1);
//cvtColor(src, hsv, CV_BGR2HSV);
//cvtColor(src1, hsv1, CV_BGR2HSV);
// Quantize the hue to 30 levels
// and the saturation to 32 levels
int hbins = 30, sbins = 32;
int histSize[] = {hbins, sbins};
// hue varies from 0 to 179, see cvtColor
float hranges[] = { 0, 180 };
// saturation varies from 0 (black-gray-white) to
// 255 (pure spectrum color)
float sranges[] = { 0, 256 };
const float* ranges[] = { hranges, sranges };
MatND hist, hist1, difference;
// we compute the histogram from the 0-th and 1-st channels
int channels[] = {0, 1};
calcHist( &three_channels[1], 1, channels, Mat(), // do not use mask
hist, 2, histSize, ranges,
true, // the histogram is uniform
false );
calcHist( &three_channels1[1], 1, channels, Mat(), // do not use mask
hist1, 2, histSize, ranges,
true, // the histogram is uniform
false );
double maxVal=0;
minMaxLoc(hist, 0, &maxVal, 0, 0);
minMaxLoc(hist1, 0, &maxVal, 0, 0);
int scale = 10;
Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
Mat hist1Img = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
Mat hist2Img = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
double hist_diff =0;
hist_diff = compareHist(hist, hist1, CV_COMP_CORREL);
absdiff(hist, hist1, difference);
printf("\nHist Diff: %f\n", hist_diff);
for( int h = 0; h < hbins; h++ )
for( int s = 0; s < sbins; s++ )
{
float binVal = hist.at<float>(h, s);
int intensity = cvRound(binVal*255/maxVal);
rectangle( histImg, Point(h*scale, s*scale),
Point( (h+1)*scale - 1, (s+1)*scale - 1),
Scalar::all(intensity),
CV_FILLED );
}
for( int h = 0; h < hbins; h++ )
for( int s = 0; s < sbins; s++ )
{
float binVal = hist1.at<float>(h, s);
int intensity = cvRound(binVal*255/maxVal);
rectangle( hist1Img, Point(h*scale, s*scale),
Point( (h+1)*scale - 1, (s+1)*scale - 1),
Scalar::all(intensity),
CV_FILLED );
}
for( int h = 0; h < hbins; h++ )
for( int s = 0; s < sbins; s++ )
{
float binVal = difference.at<float>(h, s);
int intensity = cvRound(binVal*255/maxVal);
rectangle( hist2Img, Point(h*scale, s*scale),
Point( (h+1)*scale - 1, (s+1)*scale - 1),
Scalar::all(intensity),
CV_FILLED );
}
namedWindow( "Source", 1 );
imshow( "Source", src );
namedWindow( "H-S Histogram", 1 );
imshow( "H-S Histogram", histImg );
namedWindow( "H-S Histogram1", 1 );
imshow( "H-S Histogram1", hist1Img );
namedWindow( "H-S Histogram2", 1 );
imshow( "H-S Histogram2", hist2Img );
waitKey();
}
You're trying to calculate the histogram of two channels (0 and 1) from an image that has only one channel, as you splitted it.
I did not look at your code in detail, but I guess you could omit the splitting and pass src/src1 to calcHist instead of three_channels[1]/three_channels1[1], setting channels = {1}
EDIT
In your code, change channels = {0,1} to channels{0}, you should not get any errors.
You're passing a single-channel image to calcHist(), that's why you should only use channel 0 (the only one). By passing three_channels[1] as input image, you're making sure that you're actually analysing the second channel of your input image.
OR do the following:
int channels[] = {1};
calcHist( &src, 1, channels, Mat(), // do not use mask
hist, 2, histSize, ranges,
true, // the histogram is uniform
false );
You don't need to cv::split(src,three_channels) anymore.
That's two versions that compile, but you actually want to compute a green (1D) histogram and not a 2D histogram. So here's your edited code, that (hopefully) does, what you want:
int main( int argc, char** argv )
{
Mat src,src1;
if( argc != 3 || !(src=imread(argv[1], 1)).data || !(src=imread(argv[2], 1)).data)
return -1;
// Quantize the green to 30 levels
int greenbins = 30;
int histSize[] = {greenbins};
// green varies from 0 to 255 (pure spectrum color)
float greenranges[] = { 0, 256 };
const float* ranges[] = { greenranges };
MatND hist, hist1, difference;
// we compute the histogram from the 2nd channel (green, index is 1)
int channels[] = {1};
calcHist( &src, 1, channels, Mat(), // do not use mask
hist, 1, histSize, ranges,
true, // the histogram is uniform
false );
calcHist( &src1, 1, channels, Mat(), // do not use mask
hist1, 1, histSize, ranges,
true, // the histogram is uniform
false );
double maxVal1=0;
double maxVal2 =0;
minMaxLoc(hist, 0, &maxVal1, 0, 0);
minMaxLoc(hist1, 0, &maxVal2, 0, 0);
double maxVal = max(maxVal1, maxVal2);
int scale = 10;
int width = 50;
Mat histImg = Mat::zeros(greenbins*scale, width, CV_8UC3);
Mat hist1Img = Mat::zeros(greenbins*scale, width, CV_8UC3);
Mat hist2Img = Mat::zeros(greenbins*scale, width, CV_8UC3);
double hist_diff =0;
hist_diff = compareHist(hist, hist1, CV_COMP_CORREL);
absdiff(hist, hist1, difference);
printf("\nHist Diff: %f\n", hist_diff);
for( int h = 0; h<greenbins; ++h)
{
float binVal = hist.at<float>(h);
int intensity = cvRound(binVal*255/maxVal);
rectangle( histImg, Point(0, h*scale),
Point(width, (h+1)*scale),
Scalar::all(intensity),
CV_FILLED );
}
for( int h = 0; h<greenbins; ++h)
{
float binVal = hist1.at<float>(h);
int intensity = cvRound(binVal*255/maxVal);
rectangle( hist1Img, Point(0, h*scale),
Point(width, (h+1)*scale),
Scalar::all(intensity),
CV_FILLED );
}
for(int h = 0; h < greenbins; ++h)
{
float binVal = difference.at<float>(h);
int intensity = cvRound(binVal*255/maxVal);
rectangle( hist2Img, Point(0, h*scale),
Point(width, (h+1)*scale),
Scalar::all(intensity),
CV_FILLED );
}
imshow( "Source", src );
imshow( "Source1", src1 );
imshow( "src1 green Histogram", histImg );
imshow( "src2 green Histogram", hist1Img );
imshow( "diff green Histogram", hist2Img );
waitKey();
}