Could one of you lovely people look through this and see if I’m doing anything blatantly wrong?
I get “OpenCV Error: Bad argument (Invalid histogram header) in unknown function, file src\histogram.cpp, line 1667”
.h
#pragma once
//Hacked together from [http://dasl.mem.drexel.edu/~noahKuntz/openCVTut6.html](http://dasl.mem.drexel.edu/~noahKuntz/openCVTut6.html)
#include "ofMain.h"
#include "ofxOpenCv.h"
//#define _USE_LIVE_VIDEO // uncomment this to use a live camera
// otherwise, we'll use a movie file
class testApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
#ifdef _USE_LIVE_VIDEO
ofVideoGrabber vidGrabber;
#else
ofVideoPlayer vidPlayer;
#endif
ofxCvColorImage colorImg;
ofxCvColorImage hsvImg;
ofxCvColorImage outHistImg;
ofxCvColorImage outImg;
ofxCvGrayscaleImage grayImage;
ofxCvGrayscaleImage grayBg;
ofxCvGrayscaleImage grayDiff;
ofxCvGrayscaleImage ofHplane;
ofxCvGrayscaleImage ofSplane;
ofxCvGrayscaleImage ofVplane;
IplImage* vidImage;
IplImage* img;
IplImage* back_img;
IplImage* hsv;
IplImage* h_plane;
IplImage* s_plane;
IplImage* v_plane;
IplImage* hist_img;
//IplImage* planes;
CvHistogram* hist;
unsigned char * grayDiffPixels;
int threshold;
float diffPercent;
int w;
int h;
int lastFrameCount;
bool bLearnBakground;
bool sceneChange;
int h_bins, s_bins;
};
and .cpp
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
#ifdef _USE_LIVE_VIDEO
vidGrabber.setVerbose(true);
vidGrabber.initGrabber(320,240);
#else
vidPlayer.loadMovie("movies/Nemo.mov");
vidPlayer.play();
w = vidPlayer.width;
h = vidPlayer.height;
#endif
//allocate 3 channel images
colorImg.allocate(w,h);
hsvImg.allocate(w,h);
outHistImg.allocate(w,h);
outImg.allocate(w,h);
//allocate 1 channel images
ofHplane.allocate(w,h);
ofSplane.allocate(w,h);
ofVplane.allocate(w,h);
grayImage.allocate(w,h);
grayBg.allocate(w,h);
grayDiff.allocate(w,h);
//all this is for later
bLearnBakground = true;
threshold = 20;
diffPercent = 0.20;
sceneChange = false;
grayDiffPixels = new unsigned char [w*h*3];
// Set up images as per Theron's workaround at [http://forum.openframeworks.cc/t/iplimage-to-ofxcvgrayscaleimage-problem/6873/0](http://forum.openframeworks.cc/t/iplimage-to-ofxcvgrayscaleimage-problem/6873/0)
img = colorImg.getCvImage();
back_img = grayImage.getCvImage();
hsv = hsvImg.getCvImage();
h_plane = ofHplane.getCvImage();
s_plane = ofSplane.getCvImage();
v_plane = ofVplane.getCvImage();
}
//--------------------------------------------------------------
void testApp::update(){
ofBackground(100,100,100);
bool bNewFrame = false;
#ifdef _USE_LIVE_VIDEO
vidGrabber.grabFrame();
bNewFrame = vidGrabber.isFrameNew();
#else
vidPlayer.idleMovie();
bNewFrame = vidPlayer.isFrameNew();
#endif
if (bNewFrame){
#ifdef _USE_LIVE_VIDEO
colorImg.setFromPixels(vidGrabber.getPixels(), 320,240);
#else
colorImg.setFromPixels(vidPlayer.getPixels(), w,h);
#endif
if (bLearnBakground == true){
grayBg = grayImage; // the = sign copys the pixels from grayImage into grayBg (operator overloading)
bLearnBakground = false;
}
// Compute HSV image and separate into colors
cvCvtColor( img, hsv, CV_BGR2HSV );
IplImage* planes[] = { h_plane, s_plane };//??? <--- how does this work?
cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 );
// Build and fill the histogram
int h_bins = 30, s_bins = 32;
CvHistogram* hist;
{
int hist_size[] = { h_bins, s_bins };
float h_ranges[] = { 0, 180 };
float s_ranges[] = { 0, 255 };
float* ranges[] = { h_ranges, s_ranges };
hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 );
}
cvCalcHist( planes, hist, 0, 0 ); // Compute histogram
cvNormalizeHist( hist, 20*255 ); // Normalize it
}
}
//--------------------------------------------------------------
void testApp::draw(){
ofSetHexColor(0xffffff);
colorImg = img;
colorImg.draw(20,20);
int scale = 10;
hist_img = outHistImg.getCvImage();
cvZero ( hist_img );
float max_value = 0;
cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 );
for( int h = 0; h < h_bins; h++ ){
for( int s = 0; s < s_bins; s++ ){
float bin_val = cvQueryHistValue_2D( hist, h, s );
int intensity = cvRound( bin_val * 255 / max_value );
cvRectangle( hist_img, cvPoint( h*scale, s*scale ),
cvPoint( (h+1)*scale - 1, (s+1)*scale - 1 ),
CV_RGB( intensity, intensity, intensity ),
CV_FILLED );
}
}
outImg = hist_img;
outImg.draw(600,20);
cvReleaseImage( &img );
cvReleaseImage( &back_img );
cvReleaseImage( &hist_img );
}
//--------------------------------------------------------------
void testApp::keyPressed(int key){
switch (key){
case ' ':
bLearnBakground = true;
break;
case '+':
threshold ++;
if (threshold > 255) threshold = 255;
break;
case '-':
threshold --;
if (threshold < 0) threshold = 0;
break;
case 'd':
diffPercent +=.01;
if (diffPercent > .99) diffPercent = .99;
break;
case 's':
diffPercent -=.01;
if (diffPercent < 0.01) diffPercent = 0.01;
break;
}
}
//--------------------------------------------------------------
void testApp::keyReleased(int key){
}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h){
}
//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){
}
//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){
}
Any ideas? I’m particualry concerned about the line
IplImage* planes[] = { h_plane, s_plane };
since I can’t allocate the IplImage* like I do all the others according to Theron’s workaround. I have a feeling it’s what’s causing the malformed header, but I’m not sure.
This all compiles fine and there are no errors shown in VS2010.
NovySan