Click here to Skip to main content
Click here to Skip to main content
 
Add your own
alternative version

Tagged as

ECG recording, storing, filtering and recognition

, 14 Apr 2004
Full open code project for making driver and application software for ECG medical measurements.
ecg_dsp_src.zip
drvECG_1
drvECG_1.clw
drvECG_1.def
drvECG_1.dsp
drvECG_1.dsw
drvECG_1.exp
drvECG_1.ilk
drvECG_1.lib
res
Ecg_1
ECG_1.clw
ECG_1.dsp
ECG_1.dsw
ECG_DRAW.obj
ECG_Statistic_View.lib
ECG_VIEW.exp
ECG_VIEW.ilk
ECG_VIEW.lib
TestOCX.ocx
drvECG_1.exp
drvECG_1.ilk
drvECG_1.lib
resource.hm
res
ECG_1.ico
bitmap1.bmp
bmp00001.bmp
setup.bmp
ECG_Statistic_View
ECG_Statistic_View.clw
ECG_Statistic_View.def
ECG_Statistic_View.dsp
ECG_Statistic_View.dsw
res
ECG_VIEW
ECG_DRAW.obj
ECG_VIEW.APS
ECG_VIEW.clw
ECG_VIEW.def
ECG_VIEW.dll
ECG_VIEW.dsp
ECG_VIEW.dsw
ECG_VIEW.exp
ECG_VIEW.lib
res
testrecord2.zip
georgi.ecg
test_file1.zip
test_file1.ecg
// ECG_Statistic_View1.cpp: implementation of the ECG_Statistic_View class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Statistic_View.h"
#include "Person.h"
#include "Ecg_Info.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Statistic_View::Statistic_View()
{

}

Statistic_View::~Statistic_View()
{

}
void Statistic_View::SetEcgDrawRect(CDC* pDC,CRect rDrawRect,int from,int to)
{
	//Before using this code you must specify
	//in your app the CRect&CClientDC
	//then pass them as parameters
	//in function SetEcgDrawrect
	///////////
/*	CRect rcClient;
	GetClientRect(rcClient);
	CClientDC dc(this);
*/	///////////
	dy = 25;
	//Set the rect for drawing
	m_rDrawRect = rDrawRect;
	//Get CDC pointer
	DC = pDC;
	i_from = from;
	i_to = to;
	Draw(1);
}

void Statistic_View::Draw(int d)
{
	int dx=0;
	if(d==-2)
		dx=65;
//	int DY = 100;
	//in to this class
	CBitmap Bitmap;
	CBitmap* pbmOld = NULL;//Pointer to the CBitmap object
	CDC dcMem;
	CRect BmpRect;
	BmpRect.SetRect(0,0,500*d,255*d);
	dcMem.CreateCompatibleDC(DC);//Greate painting object
	Bitmap.CreateCompatibleBitmap(DC,BmpRect.Width(),BmpRect.Height());
	//In to DCMem is getting the object bitmap
	pbmOld = dcMem.SelectObject(&Bitmap);
	//Creates the bitmap rectangle

	dcMem.PatBlt(0,0,500,255,WHITENESS);
	DrawGrid(&dcMem,BmpRect,1);
	DrawEcg(&dcMem,BmpRect,1);
	DrawFromTo(&dcMem,1);
	DrawText(&dcMem,1);

	//Shows the bitmap on the dlg screen dY=100
	DC->BitBlt(m_rDrawRect.left,m_rDrawRect.top,m_rDrawRect.right,
		m_rDrawRect.bottom,&dcMem,0,0,SRCCOPY);
	dcMem.SelectObject(pbmOld);
	dcMem.DeleteDC();

}

void Statistic_View::SetArr(double *QRS_COUNTsrc,double *PWTsrc,int lenght)
{
	if(lenght>2500)
		lenght = 2500;
	//Copy the info from pointer*source to ECG array
	for(int i=0;i<lenght;i++)
	{
		//Attencion *(ar+i)!!!
		///2 because bitmap is only 200 point height and must represent
		//up to 400 pulse and up to 400Wt power
		QRS_COUNT[i] = float(*(QRS_COUNTsrc+i)/2);
		PWT[i] = float(*(PWTsrc+i)/2);
	}

}

void Statistic_View::DrawGrid(CDC *pDC,CRect rRect,int d)
{
	int dx=0;
	if(d==-2)
	{
		dx=255;
	}
	CPen lpenR(PS_SOLID,1,RGB(180,220,180));//Select color green
	CPen* pOldpen = pDC->SelectObject(&lpenR);
	pDC->SelectObject(&lpenR);

	//draw lines horizontal
	for(int i=0;i<(200+dy)*d;i=i+25*d)
	{
		pDC->MoveTo(dx+rRect.left,i+dy+dx/2);
		pDC->LineTo(dx+rRect.right,i+dy+dx/2);
	}
	//draw vertical lines each one is equal to 1 min
	for(i=0;i<(500+dx)*d;i=i+(120)*d)
	{
		pDC->MoveTo(i+130,rRect.top+dy+dx/2);
		pDC->LineTo(i+130,rRect.bottom-dy-3-dx/2);
	}
	
	pDC->SelectObject(pOldpen);
	
	///////////////////////////////
	//printing bitmap
	for(i=0;i<10;i++)
	{
		pDC->MoveTo(255,-(100*i));
		pDC->LineTo(255+1500,-(100*i));
	}
	for(i=0;i<5;i++)
	{
		pDC->MoveTo(255+i*370,-100);
		pDC->LineTo(255+i*370,-900);
	}
	
}

void Statistic_View::DrawEcg(CDC *pDC, CRect rRect,int d)
{
		int dx=0;
	if(d==-2)
		dx=65;
/*	int i=0;
	int di=0;
	for(i=0;i<500;i++)
	{
		di = i*5;
		if(di<i_from)
		{
			pDC->MoveTo(i,30 - int(QRS_COUNT[di]));
			pDC->LineTo(i+1,30 - int(QRS_COUNT[di+5]));
		}
		if(di>i_from)
		{
			CPen lpenR(PS_SOLID,1,RGB(255,0,0));//Select color green
			CPen* pOldpen = pDC->SelectObject(&lpenR);
			pDC->SelectObject(&lpenR);
			pDC->MoveTo(i,30 - int(QRS_COUNT[di]));
			pDC->LineTo(i+1,30 - int(QRS_COUNT[di+5]));
			pDC->SelectObject(pOldpen);
		}
		if(di>i_to)
		{
	//		CPen lpenR(PS_SOLID,1,RGB(0,255,0));//Select color green
	//		CPen* pOldpen = pDC->SelectObject(&lpenR);
	//		pDC->SelectObject(&lpenR);
			pDC->MoveTo(i,30 - int(QRS_COUNT[di]));
			pDC->LineTo(i+1,30 - int(QRS_COUNT[di+5]));

	//		pDC->SelectObject(pOldpen);
		}		
	}	*/	
}

void Statistic_View::SetInfo(CString s_info)
{
	s_BmpInfo = s_info;
}

void Statistic_View::DrawText(CDC *pDC,int d)
{
	int dx=0;
	int d1=1;
	int d2=1;
	if(d==-2)
	{
		d=-4;
		dx=255;
		d1=8;
		d2=4;
	}
	CString str;
	CFont Font;
	Font.CreateFont(4*d1,4*d2,0,0,FW_DONTCARE,FALSE,FALSE,0,
		DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,
		CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,
		DEFAULT_PITCH|FF_DONTCARE,
		"MS Sans Serif");
	CFont* pOldFont = pDC->SelectObject(&Font);
	//Output the info string
	pDC->TextOut(2+dx,240*d,s_BmpInfo);
	//Output the hart rate 0-50...400beet/min
	dx=dx*5;
	for(int i=0;i<=200;i=i+25)
	{
		str.Format("%d",i*2);
		pDC->TextOut(476+dx,d*(200+dy-i-6),str);
	}
	for(i=0;i<5;i++)
	{
		str.Format("%d min",i*60);
		pDC->TextOut(i*120-i*8+dx*d,1*d,str);
		pDC->TextOut(255+350*i,-50,str);
	}
	//return the old font
	pDC->SelectObject(pOldFont);
}

void Statistic_View::DrawFromTo(CDC *pDC,int d)
{
	int dx=0;
	if(d==-2)
		dx=65;
	//draws the spesific array from position to position
	if(i_to>2500)
		i_to=2500;
	int i=0;
	for(i=i_from;i<i_to;i++)
	{
		pDC->MoveTo(d*(i*2-i_from+dx),d*(200+dy - int(QRS_COUNT[i])));
		pDC->LineTo(d*(i*2+1-i_from+dx),d*(200+dy - int(QRS_COUNT[i+1])));
	}
	//
	CPen lpenR(PS_SOLID,1,RGB(255,0,0));//Select color green
	CPen* pOldpen = pDC->SelectObject(&lpenR);
	pDC->SelectObject(&lpenR);
	for(i=i_from;i<i_to;i++)
	{
		pDC->MoveTo(d*(i*2-i_from+dx),d*(200+dy - int(PWT[i])));
		pDC->LineTo(d*(i*2+1-i_from+dx),d*(200+dy - int(PWT[i+1])));
	}
	pDC->SelectObject(pOldpen);

	//
	//Print
	for(i=0;i<2500-1;i++)
	{
		pDC->MoveTo(255+i*6,-900+PWT[i]*4);
		pDC->LineTo(255+i*6+6,-900+PWT[i+1]*4);
	}
	for(i=0;i<2500-1;i++)
	{
		pDC->MoveTo(255+i*6,-900+QRS_COUNT[i]*4);
		pDC->LineTo(255+i*6+6,-900+QRS_COUNT[i+1]*4);
	}
}

void Statistic_View::PrintBMP(CPerson* lpperson,CEcg_Info* einfo)
{
	//Problem with device pDC
	//Do not know how to enlarge the picture
	CPrintDialog dlgPrint(FALSE,PD_ALLPAGES,NULL);
	if(dlgPrint.DoModal()==IDOK)
	{
		CDC dcPrint;
		dcPrint.Attach(dlgPrint.GetPrinterDC());
		DOCINFO PrintJob;
		PrintJob.cbSize = sizeof(PrintJob);
		PrintJob.lpszDocName = "BMP printing";
		PrintJob.lpszOutput = NULL;
		PrintJob.lpszDatatype = NULL;
		PrintJob.fwType = NULL;

		dcPrint.SetMapMode(MM_LOMETRIC);
		if(dcPrint.StartDoc(&PrintJob)>=0)
		{
			int k=-2;
			CRect BmpRect;
			//enlarge width from 500->1000
			BmpRect.SetRect(0,0,500*2,255*2);
			dcPrint.StartPage();
			//Draw ECG information
			DrawGrid(&dcPrint,BmpRect,-2);
			DrawEcg(&dcPrint,BmpRect,-2);
//			DrawQRS(&dcPrint);
			DrawFromTo(&dcPrint,-2);
			DrawText(&dcPrint,-2);

			//Draw person info
			int y = DrawPersonalInfo(&dcPrint,255,-1200,lpperson);
			//Draw ECG_Info
			DrawECGInformation(&dcPrint,255,y,einfo);
			
			
			dcPrint.EndPage();
			dcPrint.EndDoc();
		}
		
		dcPrint.DeleteDC();
	}

}

int Statistic_View::DrawPersonalInfo(CDC *pDC, int x, int y,CPerson* lpperson)
{
	//Print current time
	COleDateTime curtime;
	curtime = COleDateTime::GetCurrentTime();
	y = y-40;
	pDC->TextOut(x,y,"   Printed date: "+
				curtime.Format("%dd.%mm.%Yy - %Xh"));
	//print the person information
	//Print EGN 
	y = y-80;
	pDC->TextOut(x,y,"                 Personal Info");
	y = y-45;
	pDC->TextOut(x,y,"            EGN: "+lpperson->sEGN);
	//Print birthdate
	y = y-40;
	//Format age etring
	CString sage;
	sage.Format(" - %dy.",curtime.GetYear()-lpperson->Birth_Date.GetYear());
	pDC->TextOut(x,y,"      birthdate: "+lpperson->Birth_Date.Format("%dd.%mm.%Yy")+
		sage);
	//Print name
	y =y-40;
	pDC->TextOut(x,y,"           name: "+lpperson->sName_1+" "+
		lpperson->sName_2+" "+lpperson->sName_3);
	//Print sex
	y = y-40;
	pDC->TextOut(x,y,"            sex: "+lpperson->Sex);
	//Print address
	y = y-40;
	pDC->TextOut(x,y,"        address: "+lpperson->sAddress);
	//Print phone
	y = y-40;
	pDC->TextOut(x,y,"          phone: "+lpperson->sPhone);
	return y;
}

int Statistic_View::DrawECGInformation(CDC *pDC, int x, int y, CEcg_Info *einfo)
{
	//Print ecg statistical info
		CString mean,dev,max,min;
		//Printed heart rate mean dev max min
		mean.Format("%d",einfo->HeartRate.iMean);
		dev.Format("%d",einfo->HeartRate.iDev);
		max.Format("%d",einfo->HeartRate.iMax);
		min.Format("%d",einfo->HeartRate.iMin);

		y = y-80;
		//Print velo test begin and date and time
		pDC->TextOut(x,y,"          Velo Test ECG Info - Date & Time ... "+
			einfo->velo_test_date.Format("%dd.%mm.%Yy"));

		y = y-60;
		pDC->TextOut(x,y,"              Pulse-rate/min:"+mean+
			" (+-"+dev+") ... max:"+max+" min:"+min);
		//Printed QRS_ms mean dev max min
		mean.Format("%d",einfo->QRS_ms.iMean);
		dev.Format("%d",einfo->QRS_ms.iDev);
		max.Format("%d",einfo->QRS_ms.iMax);
		min.Format("%d",einfo->QRS_ms.iMin);

		y = y-40;
		pDC->TextOut(x,y,"        QRS/ms interval mean:"+mean+
			" (+-"+dev+") ... max:"+max+" min:"+min);
		//Printed PR_ms mean dev max min
		mean.Format("%d",einfo->PR_ms.iMean);
		dev.Format("%d",einfo->PR_ms.iDev);
		max.Format("%d",einfo->PR_ms.iMax);
		min.Format("%d",einfo->PR_ms.iMin);

		y = y-40;
		pDC->TextOut(x,y,"        PR/ms  interval mean:"+mean+
			" (+-"+dev+") ... max:"+max+" min:"+min);
		//Printed QT_QTc_ms rate mean dev max min
		mean.Format("%d",einfo->QT_QTc_ms.iMean);
		dev.Format("%d",einfo->QT_QTc_ms.iDev);
		max.Format("%d",einfo->QT_QTc_ms.iMax);
		min.Format("%d",einfo->QT_QTc_ms.iMin);

		y = y-40;
		pDC->TextOut(x,y,"     QT_QTc/ms interval mean:"+mean+
			" (+-"+dev+") ... max:"+max+" min:"+min);

		//Printed Blood preasure info
		mean.Format("%d",einfo->BloodPreasure.iMean);
		dev.Format("%d",einfo->BloodPreasure.iDev);
		max.Format("%d",einfo->BloodPreasure.iMax);
		min.Format("%d",einfo->BloodPreasure.iMin);

		y = y-40;
		pDC->TextOut(x,y,"          BloodPreasure mean:"+mean+
			" (+-"+dev+") ... max:"+max+" min:"+min);

		//Printed power PWt info
		mean.Format("%d",einfo->Pwt.iMean);
		dev.Format("%d",einfo->Pwt.iDev);
		max.Format("%d",einfo->Pwt.iMax);
		min.Format("%d",einfo->Pwt.iMin);

		y = y-40;
		pDC->TextOut(x,y,"                    Pwt mean:"+mean+
			" (+-"+dev+") ... max:"+max+" min:"+min);

		//Printed power temperature info
		mean.Format("%d",einfo->Temperature.iMean);
		dev.Format("%d",einfo->Temperature.iDev);
		max.Format("%d",einfo->Temperature.iMax);
		min.Format("%d",einfo->Temperature.iMin);

		y = y-40;
		pDC->TextOut(x,y,"            Temperature mean:"+mean+
			" (+-"+dev+") ... max:"+max+" min:"+min);
		y = y-45;
		//Print information about confirmation of the raport
		pDC->TextOut(x,y,"              report confirm:"+
			einfo->Confirm_By);

		return y;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Georgi Petrov
Instructor / Trainer
Bulgaria Bulgaria
PhD, Cum Laude in digital automation systems
M.S. in Telemommunication management
B.S. in Telecommunication systems engineering
Programming: CUDA, C/C++, VHDL
Software and Hardware development and consulting:
data acquisition, image processing, medical instrumentation

| Advertise | Privacy | Mobile
Web04 | 2.8.141029.1 | Last Updated 15 Apr 2004
Article Copyright 2003 by Georgi Petrov
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid