//AdaptiveThreshold.h #ifndef ADAPTIVETHRESHOLD_H #define ADAPTIVETHRESHOLD_H #include "cv.h" #include "highgui.h" #include <QtCore/QObject> #include <QtGui/QDialog> #include <QtGui/QWidget> #include <QtGui/QHBoxLayout> #include <QtGui/QVBoxLayout> #include <QtGui/QSlider> #include <QtGui/QLabel> #include <QtGui/QImage> #include <QtGui/QPixmap> #include <QtGui/QGroupBox> #include <QtGui/QRadioButton> #include <QtGui/QLineEdit> #include <QtGui/QPushButton> #include <QtGui/QFileDialog> #include <QtGui/QComboBox> class AdaptiveThreshold:public QDialog{ Q_OBJECT public: AdaptiveThreshold(IplImage* imgRGB,QWidget* parent=0,Qt::WindowFlags f=0); ~AdaptiveThreshold(); static void Ipl2QImageRGB32(IplImage* iplImage,QImage* qImage); private Q_SLOTS: void setBlockSizeValue(); void setParam1Value(); void meanThresholding(); void gaussianThresholding(); void doThresholding(); void saveThresholdedImage(); void exitDialog(); private: //data IplImage* m_imgRGB; IplImage* m_imgGray; IplImage* m_imgTresholding; bool m_meanThresholdingFlag; bool m_gaussianThresholdingFlag; /* ** gui */ //main horizontal layout QHBoxLayout* m_mainLayout; //left vertical layout QVBoxLayout* m_leftLayout; //blockSizeSlider QHBoxLayout* m_blockSizeSliderLayout; QLabel* m_blockSizeSliderName; QSlider* m_blockSizeSlider; //param1ValueSlider QHBoxLayout* m_param1ValueSliderLayout; QLabel* m_param1ValueSliderName; QSlider* m_param1ValueSlider; //label for image QLabel* m_imageLabel; //right vertical layout QVBoxLayout* m_rightLayout; //thresholding type QGroupBox* m_thresholdingType; QVBoxLayout* m_thresholdingTypeLayout; QRadioButton* m_meanTypeButton; QRadioButton* m_gaussianTypeButton; //parameter values //block size QHBoxLayout* m_blockSizeValueLayout; QLabel* m_blockSizeValueName; QLineEdit* m_blockSizeValue; //param1 QHBoxLayout* m_param1ValueLayout; QLabel* m_param1ValueName; QLineEdit* m_param1Value; //morphological processing QComboBox* m_morphologicalType; QSlider* m_morphologicalSlider; //save the thresholded image QPushButton* m_saveThresholdedImageButton; //exit button QPushButton* m_exitButton; }; #endif
//AdaptiveThreshold.cpp #include "AdaptiveThreshold.h" AdaptiveThreshold::AdaptiveThreshold(IplImage *imgRGB, QWidget *parent, Qt::WindowFlags f):QDialog(parent,f){ m_imgRGB=cvCreateImage(cvSize(imgRGB->width,imgRGB->height),imgRGB->depth,imgRGB->nChannels); cvCopy(imgRGB,m_imgRGB); m_imgGray=cvCreateImage(cvSize(imgRGB->width,imgRGB->height),imgRGB->depth,1); cvCvtColor(m_imgRGB,m_imgGray,CV_RGB2GRAY); cvSmooth(m_imgGray,m_imgGray,CV_GAUSSIAN,3,3); m_imgTresholding=cvCreateImage(cvSize(m_imgGray->width,m_imgGray->height),m_imgGray->depth,m_imgGray->nChannels); m_meanThresholdingFlag=false; m_gaussianThresholdingFlag=false; //gui //main horizontal layout m_mainLayout=new QHBoxLayout(); //left layout m_leftLayout=new QVBoxLayout(); //blockSizeSlider m_blockSizeSliderLayout=new QHBoxLayout(); m_blockSizeSliderName=new QLabel(tr("Block Size")); m_blockSizeSlider=new QSlider(Qt::Horizontal); m_blockSizeSlider->setMinimum(0); m_blockSizeSlider->setMaximum(20); m_blockSizeSlider->setSingleStep(1); m_blockSizeSlider->setPageStep(1); m_blockSizeSlider->setValue(0); m_blockSizeSlider->setEnabled(false); QObject::connect(m_blockSizeSlider,SIGNAL(valueChanged(int)),this,SLOT(setBlockSizeValue())); QObject::connect(m_blockSizeSlider,SIGNAL(valueChanged(int)),this,SLOT(doThresholding())); m_blockSizeSliderName->setBuddy(m_blockSizeSlider); m_blockSizeSliderLayout->addWidget(m_blockSizeSliderName); m_blockSizeSliderLayout->addWidget(m_blockSizeSlider); m_leftLayout->addLayout(m_blockSizeSliderLayout); //param1ValueSlider m_param1ValueSliderLayout=new QHBoxLayout(); m_param1ValueSliderName=new QLabel(tr("Param1 Value")); m_param1ValueSlider=new QSlider(Qt::Horizontal); m_param1ValueSlider->setMaximum(1000); m_param1ValueSlider->setMinimum(-1000); m_param1ValueSlider->setSingleStep(1); m_param1ValueSlider->setValue(0); m_param1ValueSlider->setPageStep(1); m_param1ValueSlider->setEnabled(false); QObject::connect(m_param1ValueSlider,SIGNAL(valueChanged(int)),this,SLOT(setParam1Value())); QObject::connect(m_param1ValueSlider,SIGNAL(valueChanged(int)),this,SLOT(doThresholding())); m_param1ValueSliderName->setBuddy(m_param1ValueSlider); m_param1ValueSliderLayout->addWidget(m_param1ValueSliderName); m_param1ValueSliderLayout->addWidget(m_param1ValueSlider); m_leftLayout->addLayout(m_param1ValueSliderLayout); //label for image m_imageLabel=new QLabel(); QImage* qImage=new QImage(m_imgRGB->width,m_imgRGB->height,QImage::Format_RGB32); Ipl2QImageRGB32(m_imgRGB,qImage); QPixmap* pixmapImage=new QPixmap(); m_imageLabel->setPixmap(pixmapImage->fromImage(*qImage)); m_leftLayout->addWidget(m_imageLabel); //right layout m_rightLayout=new QVBoxLayout(); m_thresholdingType=new QGroupBox(tr("types of thresholding")); m_thresholdingTypeLayout=new QVBoxLayout(); m_meanTypeButton=new QRadioButton(tr("mean"),m_thresholdingType); m_thresholdingTypeLayout->addWidget(m_meanTypeButton); QObject::connect(m_meanTypeButton,SIGNAL(clicked()),this,SLOT(meanThresholding())); m_gaussianTypeButton=new QRadioButton(tr("gaussian"),m_thresholdingType); m_thresholdingTypeLayout->addWidget(m_gaussianTypeButton); QObject::connect(m_gaussianTypeButton,SIGNAL(clicked()),this,SLOT(gaussianThresholding())); m_thresholdingType->setLayout(m_thresholdingTypeLayout); m_rightLayout->addWidget(m_thresholdingType); //parameter values //block size m_blockSizeValueLayout=new QHBoxLayout(); m_blockSizeValueName=new QLabel(tr("Block Size")); m_blockSizeValue=new QLineEdit(); m_blockSizeValueName->setBuddy(m_blockSizeValue); m_blockSizeValue->setText(QString::number((double)(m_blockSizeSlider->value()*2+3))); m_blockSizeValueLayout->addWidget(m_blockSizeValueName); m_blockSizeValueLayout->addWidget(m_blockSizeValue); m_rightLayout->addLayout(m_blockSizeValueLayout); //param1 m_param1ValueLayout= new QHBoxLayout(); m_param1ValueName=new QLabel("Param1 value"); m_param1Value= new QLineEdit(); m_param1ValueName->setBuddy(m_param1Value); m_param1Value->setText(QString::number((double)m_param1ValueSlider->value())); m_param1ValueLayout->addWidget(m_param1ValueName); m_param1ValueLayout->addWidget(m_param1Value); m_rightLayout->addLayout(m_param1ValueLayout); //morphological processing m_morphologicalType=new QComboBox(); m_morphologicalType->addItem(QString("Open")); m_morphologicalType->addItem(QString("Close")); m_rightLayout->addWidget(m_morphologicalType); m_morphologicalSlider=new QSlider(Qt::Horizontal); m_morphologicalSlider->setMinimum(0); m_morphologicalSlider->setMaximum(7); m_morphologicalSlider->setSingleStep(1); m_morphologicalSlider->setPageStep(1); m_morphologicalSlider->setValue(0); m_morphologicalSlider->setEnabled(false); m_rightLayout->addWidget(m_morphologicalSlider); QObject::connect(m_morphologicalSlider,SIGNAL(valueChanged(int)),this,SLOT(doThresholding())); //save the thresholded image m_saveThresholdedImageButton=new QPushButton(tr("&Save Thresholded Image")); m_rightLayout->addWidget(m_saveThresholdedImageButton); QObject::connect(m_saveThresholdedImageButton,SIGNAL(clicked()),this,SLOT(saveThresholdedImage())); //exit button m_exitButton=new QPushButton(tr("&Exit")); m_rightLayout->addWidget(m_exitButton); QObject::connect(m_exitButton,SIGNAL(clicked()),this,SLOT(exitDialog())); m_mainLayout->addLayout(m_leftLayout); m_mainLayout->addLayout(m_rightLayout); this->setLayout(m_mainLayout); } AdaptiveThreshold::~AdaptiveThreshold(){ cvReleaseImage(&m_imgRGB); cvReleaseImage(&m_imgGray); cvReleaseImage(&m_imgTresholding); } void AdaptiveThreshold::setBlockSizeValue(){ m_blockSizeValue->setText(QString::number((double)(m_blockSizeSlider->value()*2+3))); } void AdaptiveThreshold::setParam1Value(){ m_param1Value->setText(QString::number(((double)m_param1ValueSlider->value())/10.0)); } void AdaptiveThreshold::meanThresholding(){ if(!m_blockSizeSlider->isEnabled()){ m_blockSizeSlider->setEnabled(true); } if(!m_param1ValueSlider->isEnabled()){ m_param1ValueSlider->setEnabled(true); } if(!m_morphologicalSlider->isEnabled()){ m_morphologicalSlider->setEnabled(true); } m_meanThresholdingFlag=true; m_gaussianThresholdingFlag=false; doThresholding(); } void AdaptiveThreshold::gaussianThresholding(){ if(!m_blockSizeSlider->isEnabled()){ m_blockSizeSlider->setEnabled(true); } if(!m_param1ValueSlider->isEnabled()){ m_param1ValueSlider->setEnabled(true); } if(!m_morphologicalSlider->isEnabled()){ m_morphologicalSlider->setEnabled(true); } m_meanThresholdingFlag=false; m_gaussianThresholdingFlag=true; doThresholding(); } void AdaptiveThreshold::doThresholding(){ //thresholding if(m_meanThresholdingFlag){ cvAdaptiveThreshold(m_imgGray,m_imgTresholding,255.0,CV_ADAPTIVE_THRESH_MEAN_C,CV_THRESH_BINARY,m_blockSizeSlider->value()*2+3,((double)m_param1ValueSlider->value())/10.0); } else if(m_gaussianThresholdingFlag){ cvAdaptiveThreshold(m_imgGray,m_imgTresholding,255.0,CV_ADAPTIVE_THRESH_GAUSSIAN_C,CV_THRESH_BINARY,m_blockSizeSlider->value()*2+3,((double)m_param1ValueSlider->value())/10.0); } //morphological processing IplConvKernel* crossKernel=cvCreateStructuringElementEx(m_morphologicalSlider->value()*2+3,m_morphologicalSlider->value()*2+3,m_morphologicalSlider->value()+1,m_morphologicalSlider->value()+1,CV_SHAPE_CROSS); if(m_morphologicalType->currentText().compare(QString("Open"))==0){ cvMorphologyEx(m_imgTresholding,m_imgTresholding,0,crossKernel,CV_MOP_OPEN); } else if(m_morphologicalType->currentText().compare(QString("Close"))==0){ cvMorphologyEx(m_imgTresholding,m_imgTresholding,0,crossKernel,CV_MOP_CLOSE); } QImage* qImage=new QImage(m_imgTresholding->width,m_imgTresholding->height,QImage::Format_RGB32); Ipl2QImageRGB32(m_imgTresholding,qImage); QPixmap* pixmapImage=new QPixmap(); m_imageLabel->setPixmap(pixmapImage->fromImage(*qImage)); } void AdaptiveThreshold::saveThresholdedImage(){ QString imgName=QFileDialog::getSaveFileName(0,tr("Save Thresholded Image Name"),"thresholdedImage.jpg",tr("Image (*.jpg)")); cvSaveImage(imgName.toLatin1().data(),m_imgTresholding); } void AdaptiveThreshold::exitDialog(){ this->done(1); } void AdaptiveThreshold::Ipl2QImageRGB32(IplImage* iplImage,QImage* qImage){ unsigned char* ptrQImage=qImage->bits(); switch(iplImage->depth){ case IPL_DEPTH_8U: if(iplImage->nChannels==1){ for(int row=0;row<iplImage->height;row++){ unsigned char* ptr=(unsigned char*)(iplImage->imageData+row*iplImage->widthStep); for(int col=0;col<iplImage->width;col++){ *(ptrQImage)=*(ptr+col); *(ptrQImage+1)=*(ptr+col); *(ptrQImage+2)=*(ptr+col); *(ptrQImage+3)=0; ptrQImage+=4; } } } else if(iplImage->nChannels==3){ for(int row=0;row<iplImage->height;row++){ unsigned char* ptr=(unsigned char*)(iplImage->imageData+row*iplImage->widthStep); for(int col=0;col<iplImage->width;col++){ *(ptrQImage)=*(ptr+col*3); *(ptrQImage+1)=*(ptr+col*3+1); *(ptrQImage+2)=*(ptr+col*3+2); *(ptrQImage+3)=0; ptrQImage+=4; } } } break; case IPL_DEPTH_32F: if(iplImage->nChannels==1){ for(int row=0;row<iplImage->height;row++){ float* ptr=(float*)(iplImage->imageData+row*iplImage->widthStep); for(int col=0;col<iplImage->width;col++){ *(ptrQImage)=(unsigned char)(*(ptr+col)*255.0); *(ptrQImage+1)=(unsigned char)(*(ptr+col)*255.0); *(ptrQImage+2)=(unsigned char)(*(ptr+col)*255.0); *(ptrQImage+3)=0; ptrQImage+=4; } } } else if(iplImage->nChannels==3){ for(int row=0;row<iplImage->height;row++){ float* ptr=(float*)(iplImage->imageData+row*iplImage->widthStep); for(int col=0;col<iplImage->width;col++){ *(ptrQImage)=(unsigned char)(*(ptr+col*3)*255.0); *(ptrQImage+1)=(unsigned char)(*(ptr+col*3+1)*255.0); *(ptrQImage+2)=(unsigned char)(*(ptr+col*3+2)*255.0); *(ptrQImage+3)=0; ptrQImage+=4; } } } break; case IPL_DEPTH_64F: if(iplImage->nChannels==1){ for(int row=0;row<iplImage->height;row++){ double* ptr=(double*)(iplImage->imageData+row*iplImage->widthStep); for(int col=0;col<iplImage->width;col++){ *(ptrQImage)=(unsigned char)(*(ptr+col)*255.0); *(ptrQImage+1)=(unsigned char)(*(ptr+col)*255.0); *(ptrQImage+2)=(unsigned char)(*(ptr+col)*255.0); *(ptrQImage+3)=0; ptrQImage+=4; } } } else if(iplImage->nChannels==3){ for(int row=0;row<iplImage->height;row++){ double* ptr=(double*)(iplImage->imageData+row*iplImage->widthStep); for(int col=0;col<iplImage->width;col++){ *(ptrQImage)=(unsigned char)(*(ptr+col*3)*255.0); *(ptrQImage+1)=(unsigned char)(*(ptr+col*3+1)*255.0); *(ptrQImage+2)=(unsigned char)(*(ptr+col*3+2)*255.0); *(ptrQImage+3)=0; ptrQImage+=4; } } } break; default: printf("The type of the IplImage should be IPL_DEPTH_8U,IPL_DEPTH_32F or IPL_DEPTH_64F"); } }
//main.cpp #include "AdaptiveThreshold.h" #include <QtGui/QApplication> int main(int argc,char** argv){ QApplication app(argc,argv); IplImage* img=cvLoadImage("data/videoImage.jpg",1); AdaptiveThreshold testDialog(img); int ret=testDialog.exec(); return app.exec(); }