Hi all, I am working on an OpenCV project and I need to compare some images after canny has been applied to both of them. Before the canny was applied I had the gray scale images populating a histogram and then I compared the histograms, but when canny is added to the images the histogram does not populate. I have read that a canny image can populate a histogram, but have not found a way to make it happen. I do not necessairly need to keep using the histograms, I just want to know the best way to compare two canny images. SSCCE below for you to chew on. I have poached and patched about 75% of this code from books and various sites on the internet, so props to those guys...
// SLC (Histogram).cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <cxcore.h>
#include <cv.h>
#include <cvaux.h>
#include <highgui.h>
#include <stdio.h>
#include <sstream>
#include <iostream>
using namespace std;
IplImage* image1= 0;
IplImage* imgHistogram1 = 0;
IplImage* gray1= 0;
CvHistogram* hist1;
int main(){
CvCapture* capture = cvCaptureFromCAM(0);
if(!cvQueryFrame(capture)){
cout<<"Video capture failed, please check the camera."<<endl;
}
else{
cout<<"Video camera capture successful!"<<endl;
};
CvSize sz = cvGetSize(cvQueryFrame(capture));
IplImage* image = cvCreateImage(sz, 8, 3);
IplImage* imgHistogram = 0;
IplImage* gray = 0;
CvHistogram* hist;
cvNamedWindow("Image Source",1);
cvNamedWindow("gray", 1);
cvNamedWindow("Histogram",1);
cvNamedWindow("BG", 1);
cvNamedWindow("FG", 1);
cvNamedWindow("Canny",1);
cvNamedWindow("Canny1", 1);
image1 = cvLoadImage("image bin/use this image.jpg");// an image has to load here or the program will not run
//size of the histogram -1D histogram
int bins1 = 256;
int hsize1[] = {bins1};
//max and min value of the histogram
float max_value1 = 0, min_value1 = 0;
//value and normalized value
float value1;
int normalized1;
//ranges - grayscale 0 to 256
float xranges1[] = { 0, 256 };
float* ranges1[] = { xranges1 };
//create an 8 bit single channel image to hold a
//grayscale version of the original picture
gray1 = cvCreateImage( cvGetSize(image1), 8, 1 );
cvCvtColor( image1, gray1, CV_BGR2GRAY );
IplImage* canny1 = cvCreateImage(cvGetSize(gray1), 8, 1 );
cvCanny( gray1, canny1, 55, 175, 3 );
//Create 3 windows to show the results
cvNamedWindow("original1",1);
cvNamedWindow("gray1",1);
cvNamedWindow("histogram1",1);
//planes to obtain the histogram, in this case just one
IplImage* planes1[] = { canny1 };
//get the histogram and some info about it
hist1 = cvCreateHist( 1, hsize1, CV_HIST_ARRAY, ranges1,1);
cvCalcHist( planes1, hist1, 0, NULL);
cvGetMinMaxHistValue( hist1, &min_value1, &max_value1);
printf("min: %f, max: %f\n", min_value1, max_value1);
//create an 8 bits single channel image to hold the histogram
//paint it white
imgHistogram1 = cvCreateImage(cvSize(bins1, 50),8,1);
cvRectangle(imgHistogram1, cvPoint(0,0), cvPoint(256,50), CV_RGB(255,255,255),-1);
//draw the histogram :P
for(int i=0; i < bins1; i++){
value1 = cvQueryHistValue_1D( hist1, i);
normalized1 = cvRound(value1*50/max_value1);
cvLine(imgHistogram1,cvPoint(i,50), cvPoint(i,50-normalized1), CV_RGB(0,0,0));
}
//show the image results
cvShowImage( "original1", image1 );
cvShowImage( "gray1", gray1 );
cvShowImage( "histogram1", imgHistogram1 );
cvShowImage( "Canny1", canny1);
CvBGStatModel* bg_model = cvCreateFGDStatModel( image );
for(;;){
image = cvQueryFrame(capture);
cvUpdateBGStatModel( image, bg_model );
//Size of the histogram -1D histogram
int bins = 256;
int hsize[] = {bins};
//Max and min value of the histogram
float max_value = 0, min_value = 0;
//Value and normalized value
float value;
int normalized;
//Ranges - grayscale 0 to 256
float xranges[] = {0, 256};
float* ranges[] = {xranges};
//Create an 8 bit single channel image to hold a grayscale version of the original picture
gray = cvCreateImage(cvGetSize(image), 8, 1);
cvCvtColor(image, gray, CV_BGR2GRAY);
IplImage* canny = cvCreateImage(cvGetSize(gray), 8, 1 );
cvCanny( gray, canny, 55, 175, 3 );//55, 175, 3 with direct light
//Planes to obtain the histogram, in this case just one
IplImage* planes[] = {canny};
//Get the histogram and some info about it
hist = cvCreateHist(1, hsize, CV_HIST_ARRAY, ranges,1);
cvCalcHist(planes, hist, 0, NULL);
cvGetMinMaxHistValue(hist, &min_value, &max_value);
//printf("Minimum Histogram Value: %f, Maximum Histogram Value: %f\n", min_value, max_value);
//Create an 8 bits single channel image to hold the histogram and paint it white
imgHistogram = cvCreateImage(cvSize(bins, 50),8,3);
cvRectangle(imgHistogram, cvPoint(0,0), cvPoint(256,50), CV_RGB(255,255,255),-1);
//Draw the histogram
for(int i=0; i < bins; i++){
value = cvQueryHistValue_1D(hist, i);
normalized = cvRound(value*50/max_value);
cvLine(imgHistogram,cvPoint(i,50), cvPoint(i,50-normalized), CV_RGB(0,0,0));
}
double correlation = cvCompareHist (hist1, hist, CV_COMP_CORREL);
double chisquare = cvCompareHist (hist1, hist, CV_COMP_CHISQR);
double intersection = cvCompareHist (hist1, hist, CV_COMP_INTERSECT);
double bhattacharyya = cvCompareHist (hist1, hist, CV_COMP_BHATTACHARYYA);
double difference = (1 - correlation) + chisquare + (1 - intersection) + bhattacharyya;
printf("correlation: %f\n", correlation);
printf("chi-square: %f\n", chisquare);
printf("intersection: %f\n", intersection);
printf("bhattacharyya: %f\n", bhattacharyya);
printf("difference: %f\n", difference);
cvShowImage("Image Source", image);
cvShowImage("gray", gray);
cvShowImage("Histogram", imgHistogram);
cvShowImage( "Canny", canny);
cvShowImage("BG", bg_model->background);
cvShowImage("FG", bg_model->foreground);
//Page 19 paragraph 3 of "Learning OpenCV" tells us why we DO NOT use "cvReleaseImage(&image)" in this section
cvReleaseImage(&imgHistogram);
cvReleaseImage(&gray);
cvReleaseHist(&hist);
cvReleaseImage(&canny);
char c = cvWaitKey(10);
//if ASCII key 27 (esc) is pressed then loop breaks
if(c==27) break;
}
cvReleaseBGStatModel( &bg_model );
cvReleaseImage(&image);
cvReleaseCapture(&capture);
cvDestroyAllWindows();
}