一个基于Qt的用cvAdaptiveThreshold二值化图像的程序

//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();
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值