⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classifierdlg.cpp

📁 使用SVM分类的方法
💻 CPP
字号:
// ClassifierDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Classifier.h"
#include "ClassifierDlg.h"
#include "svm.h"
#include <list>
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
int XLEN , YLEN;
CWnd *pMainWnd;
list<point> point_list;
HBRUSH brush1,brush2,	brush3 ;
HDC window_dc;
HBITMAP buffer;
HDC buffer_dc;
COLORREF colors[] =
{
	RGB(0,0,0),
	RGB(0,120,120),
	RGB(120,120,0),
	RGB(120,0,120),
	RGB(0,200,200),
	RGB(200,200,0),
	RGB(200,0,200)
};
svm_problem prob;
svm_model *model;
svm_parameter param;
svm_node *x_space;
	svm_node x[3];

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClassifierDlg dialog

CClassifierDlg::CClassifierDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CClassifierDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CClassifierDlg)
	m_strFemaleFileName = _T("");
	m_strMaleFileName = _T("");
	m_strTestFileName = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	pMainWnd=this;
}

void CClassifierDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CClassifierDlg)
	DDX_Text(pDX, IDC_EDITFEMALE, m_strFemaleFileName);
	DDX_Text(pDX, IDC_EDITMALE, m_strMaleFileName);
	DDX_Text(pDX, IDC_EDITTEST, m_strTestFileName);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CClassifierDlg, CDialog)
	//{{AFX_MSG_MAP(CClassifierDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_DATASCALE, OnDatascale)
	ON_BN_CLICKED(IDC_TEST, OnTest)
	ON_BN_CLICKED(IDC_MALE, OnMale)
	ON_BN_CLICKED(IDC_FEMALE, OnFemale)
	ON_BN_CLICKED(IDC_LOADTEXT, OnLoadtext)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClassifierDlg message handlers

BOOL CClassifierDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	brush1 = CreateSolidBrush(colors[4]);
	brush2 = CreateSolidBrush(colors[5]);
	brush3 = CreateSolidBrush(colors[6]);

    GetDlgItem(IDC_TESTDRAW)->GetClientRect(&rect1);
	XLEN =rect1.Width();
	YLEN=rect1.Height();

	window_dc =GetDlgItem(IDC_TESTDRAW)->GetDC()->m_hDC;
	buffer = CreateCompatibleBitmap(window_dc, XLEN, YLEN);
	buffer_dc = CreateCompatibleDC(window_dc);
		SelectObject(buffer_dc, buffer);
	PatBlt(buffer_dc, 0, 0, XLEN, YLEN, BLACKNESS);
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CClassifierDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CClassifierDlg::OnPaint() 
{
    HDC hdc;
	PAINTSTRUCT ps;
	HWND hwnd=GetDlgItem(IDC_TESTDRAW)->m_hWnd;
	hdc = ::BeginPaint(hwnd, &ps);
	::BitBlt(hdc, 0, 0, XLEN, YLEN, buffer_dc, 0, 0, SRCCOPY);
	::EndPaint(hwnd, &ps);
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
	

}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CClassifierDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CClassifierDlg::OnDatascale() 
{
	// TODO: Add your control notification handler code here
	float height,weight;
	FILE *fileMale=fopen(m_strMaleFileName,"r"); 
	FILE *fileFemale=fopen(m_strFemaleFileName,"r"); 
	FILE *fileResult=fopen("result.txt","w"); 
	int xingbie=1;//1表示MALE

	while (TRUE)
	{
		//读身高数据
		if(EOF==fscanf(fileMale,"%f",&height))
		{
			
			break;
		}
		fprintf(fileResult,"%d",xingbie);
		fprintf(fileResult,"%c",' ');
		fprintf(fileResult,"%d",1);
        fprintf(fileResult,"%c",':');
		fprintf(fileResult,"%f",height/HEIGHT_SCALE);
		fprintf(fileResult,"%c",' ');
		
        //读取体重数据
		if(EOF==fscanf(fileMale,"%f",&weight))
		{
			
			break;
		}
		fprintf(fileResult,"%d",2);
        fprintf(fileResult,"%c",':');
		fprintf(fileResult,"%f",weight/WEIGHT_SCALE);
		fprintf(fileResult,"%c",'\n');
	}
	xingbie=-1;//1表示FEMALE
	while (TRUE)
	{
		//读身高数据
		if(EOF==fscanf(fileFemale,"%f",&height))
		{
			
			break;
		}
		fprintf(fileResult,"%d",xingbie);
		fprintf(fileResult,"%c",' ');
		fprintf(fileResult,"%d",1);
        fprintf(fileResult,"%c",':');
		fprintf(fileResult,"%f",height/HEIGHT_SCALE);
		fprintf(fileResult,"%c",' ');
		
        //读取体重数据
		if(EOF==fscanf(fileFemale,"%f",&weight))
		{
			
			break;
		}
		fprintf(fileResult,"%d",2);
        fprintf(fileResult,"%c",':');
		fprintf(fileResult,"%f",weight/WEIGHT_SCALE);
		fprintf(fileResult,"%c",'\n');
	}
	
	//fscanf(file,"%c",&c);
	//fscanf(file,"%f",&weight);
	fclose(fileMale);
	fclose(fileFemale);
	fclose(fileResult);

	
}

void CClassifierDlg::OnTest() 
{
	// TODO: Add your control notification handler code here
	FILE *fp = fopen("result.txt","r");	
						if(fp)
						{
							char buf[4096];
							while(fgets(buf,sizeof(buf),fp))
							{
								int v;
								double x,y;
								if(sscanf(buf,"%d%*d:%lf%*d:%lf",&v,&x,&y)!=3)
									break;
								point p = {x,y,v};
								point_list.push_back(p);
							}
							fclose(fp);
							draw_all_points();
						}
			if(point_list.empty()) return;


	int i,j;
	
	// default values
	param.svm_type = C_SVC;
	param.kernel_type =POLY;
	param.degree = 3;
	param.gamma = 0;
	param.coef0 = 0;
	param.nu = 0.5;
	param.cache_size = 100;
	param.C = 1000;
	param.eps = 1e-10;
	param.p = 0.1;
	param.shrinking = 1;
	param.probability = 0;
	param.nr_weight = 0;
	param.weight_label = NULL;
	param.weight = NULL;
	// build problem


	prob.l = point_list.size();
	prob.y = new double[prob.l];
		if(param.gamma == 0) param.gamma = 0.5;
		x_space = new svm_node[3 * prob.l];
		prob.x = new svm_node *[prob.l];

		i = 0;
		for (list<point>::iterator q = point_list.begin(); q != point_list.end(); q++, i++)
		{
			x_space[3 * i].index = 1;
			x_space[3 * i].value = q->x;
			x_space[3 * i + 1].index = 2;
			x_space[3 * i + 1].value = q->y;
			x_space[3 * i + 2].index = -1;
			prob.x[i] = &x_space[3 * i];
			prob.y[i] = q->value;
		}

		// build model & classify
	 model = svm_train(&prob, &param);
	
		x[0].index = 1;
		x[1].index = 2;
		x[2].index = -1;

		for (i = 0; i < XLEN; i++)
			for (j = 0; j < YLEN; j++) 
			{
				x[0].value = (double) i / XLEN;
				x[1].value = (double) j / YLEN;
				double d = svm_predict(model, x);
				if (param.svm_type == ONE_CLASS && d<0) d=2;
				SetPixel(window_dc, i, j, colors[(int)d]);
				SetPixel(buffer_dc, i, j, colors[(int)d]);
			}


	draw_all_points();
	


}

void CClassifierDlg::OnMale() 
{
	// TODO: Add your control notification handler code here
	CFileDialog   dlg(TRUE,   NULL,   NULL,   OFN_FILEMUSTEXIST|   OFN_HIDEREADONLY,     
		"TXT文件 (*.txt)|*.txt||", this);   
	
	if(dlg.DoModal()!=IDOK)   
		return;   
      m_strMaleFileName =   dlg.GetPathName();
	((CClassifierDlg *)pMainWnd)->GetDlgItem(IDC_EDITMALE)->SetWindowText(m_strMaleFileName);
    

}

void CClassifierDlg::OnFemale() 
{
	// TODO: Add your control notification handler code here
		CFileDialog   dlg(TRUE,   NULL,   NULL,   OFN_FILEMUSTEXIST|   OFN_HIDEREADONLY,     
		"TXT文件 (*.txt)|*.txt||", this);   
	
	if(dlg.DoModal()!=IDOK)   
		return;   
	
    m_strFemaleFileName  =   dlg.GetPathName();
	((CClassifierDlg *)pMainWnd)->GetDlgItem(IDC_EDITFEMALE)->SetWindowText( m_strFemaleFileName);
	
}

void CClassifierDlg::draw_point(const point &p)
{
	RECT rect;
    rect.left = int(p.x*XLEN);
	rect.top = int(p.y*YLEN);
	rect.right = int(p.x*XLEN) + 3;
	rect.bottom = int(p.y*YLEN) + 3;
	FillRect(window_dc, &rect, choose_brush(p.value));
	FillRect(buffer_dc, &rect, choose_brush(p.value));



}

void CClassifierDlg::draw_all_points()
{
	for(list<point>::iterator p = point_list.begin(); p != point_list.end(); p++)
		draw_point(*p);

}

HBRUSH CClassifierDlg::choose_brush(int v)
{
	if(v==1) return brush1;
	else if(v==-1) return brush2;
	else return brush3;

}

void CClassifierDlg::OnLoadtext() 
{
	// TODO: Add your control notification handler code here
	float height,weight;
	char xingbie;
	int total=0,error=0;
	int v;
	double m,n;
	point p = {m,n,v};
	CFileDialog   dlg(TRUE,   NULL,   NULL,   OFN_FILEMUSTEXIST|   OFN_HIDEREADONLY,     
		"TXT文件 (*.txt)|*.txt||", this);   
	
	if(dlg.DoModal()!=IDOK)   
		return;   
	point_list.clear();
	PatBlt(buffer_dc, 0, 0, XLEN, YLEN, BLACKNESS);
	::InvalidateRect(GetDlgItem(IDC_TESTDRAW)->m_hWnd, 0, 0);
	
	for (int i = 0; i < XLEN; i++)
		for (int j = 0; j < YLEN; j++) 
		{
			x[0].value = (double) i / XLEN;
			x[1].value = (double) j / YLEN;
			double d = svm_predict(model, x);
			if (param.svm_type == ONE_CLASS && d<0) d=2;
			SetPixel(window_dc, i, j, colors[(int)d]);
			SetPixel(buffer_dc, i, j, colors[(int)d]);
		}
		
		m_strTestFileName =   dlg.GetPathName();
		((CClassifierDlg *)pMainWnd)->GetDlgItem(IDC_EDITTEST)->SetWindowText(m_strTestFileName);
		
		FILE *testFile=fopen(m_strTestFileName,"r"); 
		if (testFile)
		{
			
			while (TRUE)
			{
				//读身高数据
				if(EOF==fscanf(testFile,"%f",&height))
				{
					
					break;
				}
				p.x=height/HEIGHT_SCALE;
				
				if(EOF==fscanf(testFile,"%f",&weight))
				{
					
					break;
				}
				p.y=weight/WEIGHT_SCALE;
				if(EOF==fscanf(testFile,"%*c%c",&xingbie))
				{
					
					break;
				}
				if ((xingbie=='f')||(xingbie=='F'))
				{
					
					p.value=-1;
				}
				else
				{
					p.value=1;
					
				}
				
				point_list.push_back(p);
				x[0].value =p.x;
				x[1].value=p.y;
				double d = svm_predict(model, x);
				if ((int)d==p.value)
				{
				}
				else
					error++;
			total++;
				
			}
			draw_all_points();
			CString str;
			str.Format("%f%%",100.0-100*((float)error)/((float)total));
			MessageBox(str);
			
			fclose(testFile);
			
		}
		if(point_list.empty()) return;

	}



void CClassifierDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here

		delete[] x_space;
		delete[] prob.x;
		delete[] prob.y;
	svm_destroy_model(model);
	free(param.weight_label);
	free(param.weight);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -