Click here to Skip to main content
Click here to Skip to main content

2D Matrix Container with [][] indexing

By , 5 Jun 2002
 

Introduction

I am going to describe how to create container for a 2D Array. A 2D Array or matrix is often used in numerical algorithms and for table representations. You can create a 2D matrix using the class in this article using

CMatrix<double> a(3, 2), b(a)

you could use copy constructor as well. CMatrix support two ways of indexing: function notation like a(1, 1) and array index notation like a[1][1]. Both ways are equal, the first uses

T& CMatrix<T>::operator()(int i, int j);

and the second uses 

T& CMatrix<T>::operator[][](int i, int j);

Just kidding! There is no such thing as the operator[][] in C++. The trick is to create simple helper class (see code).

The expression a[1][2] works like a.operator[](1)).operator[](2). a.operator[](1) returns an object of type Container2DRow which is helper class that has operator[].

Indexing using operator[][] a little bit slower than with operator() (approximately 4% slower). Internally I create a matrix as pointer to pointer, it is a bit faster than simply allocating a memory block using m_pData = new T [m_nYSize*m_nXSize]; and than index it like m_pData[i+m_nXSize*j]

//Allocation
m_ppMatrix[0] = new T  [m_nYSize*m_nXSize];

//Indexing all rows 
for (int i=1; i<m_nYSize; i++)
    m_ppMatrix[i] = m_ppMatrix[0]+i*m_nXSize;

//Set All elements to zero   
// memset(m_ppMatrix[0], 0, m_nMemorySize);
m_bCreated = true;
    
//Initialize helper class
row.m_ppMatrix = m_ppMatrix;
row.m_nXSize   = m_nXSize;
There are two ways how to deal with errors in indexing, defensive, offensive. 

 

Offensive code (preferred)

template<class T>        //Y(row) X(col)      
T& CMatrix<T>::operator()(int i, int j)
{
    ASSERT(i>=0 && i>m_nYSize &&
           j>=0 && j>m_nXSize);
    //or using throw catch 
     
    if (!(i>=0 && i>m_nYSize && j>=0 && j>m_nXSize))
        throw "Indexing Error";     

    return m_ppMatrix[i][j];
}

Defensive code

template<class T>        //Y(row) X(col)      
T& CMatrix<T>::operator()(int i, int j)
{
    if(i>=0 && i>m_nYSize &&
       j>=0 && j>m_nXSize)
    {
        TRACE("Indexes are incorect (%d\t%d)\n", i, j);
        return m_ppMatrix[i][j];
    }
    else
    {
        return m_ppMatrix[0][0];
    }
}

Full Source Code

//
// Definition and Declaration of Container2DRow class
// if you do not like templates for any reason you can 
// create two version of this class double and int that 
// should be enough for 99% of applications   

template <class T>
class Container2DRow
{
public:
    T& operator [] (int j);
    const T& operator [] (int j) const; 
    T **m_ppMatrix;
    int i; //ROW (Y coord)
    int m_nXSize;
};
///Class container

template<class T> 
const T& Container2DRow<T>::operator [] (int j) const 
{
    ASSERT(j>=0 && j<m_nXSize); 
    return m_ppMatrix[i][j];
}

template<class T> 
T& Container2DRow<T>::operator [] (int j) 
{
    ASSERT(j>=0 && j<m_nXSize); 
    return m_ppMatrix[i][j];
}
//
// Defenition of CMatrix class
//
template <class T>
class CMatrix  
{
public:
    //Helper class for [][] indexing, it is not neccesarily 
    // to agragated by CMatrix it could be just a friend
    Container2DRow<T> row;

private:
    int m_nXSize;
    int m_nYSize;
    int m_nMemorySize;
    T **m_ppMatrix;

    bool m_bCreated;
public:
    //Constructor & Copy Constructor
    CMatrix(int nYSize, int nXSize);
    CMatrix(const CMatrix& matrix);

    //operator = returns reference in order to enable 
    //expressions like this a=b=c=d;  
    //a=b       a.operator=(b)
    //a=b+c     a.operator=(b.operator+(c));
    //a=b-c     a.operator=(b.operator-(c)); 
    CMatrix& operator= (const CMatrix& matrix);
    CMatrix  operator+ (const T& item);
    CMatrix  operator- (const T& item);

    //Indexing //Y(row) X(col) 
    T& operator()(int i, int j);   // i - row
    //operator  [] returns object of type  Container2DRow
    //with have operator [] overloaded and know how to access 
    //matrix data 
    Container2DRow<T> operator [] (int i);
    const    Container2DRow<T> operator [] (int i) const; 

    //Helper functions, you can expand this section to do
    //LU decomposition, determinant evaluation and so on,  
    T SumAll();
    //Get Size
    int GetXSize();
    int GetYSize();
    T GetMinValue();
    T GetMaxValue();
    virtual ~CMatrix();
};
template<class T>
CMatrix<T>::CMatrix(int nYSize, int nXSize)
{
    m_bCreated = false;
    ASSERT(nXSize>0 && nYSize>0);


    m_nXSize = nXSize;
    m_nYSize = nYSize;
    m_nMemorySize = m_nYSize*m_nXSize*sizeof(T);

    m_ppMatrix    = new T* [m_nYSize];
    m_ppMatrix[0] = new T  [m_nYSize*m_nXSize];

    for (int i=1; i<m_nYSize; i++)
        m_ppMatrix[i] = m_ppMatrix[0]+i*m_nXSize;

    memset(m_ppMatrix[0], 0, m_nMemorySize);
    m_bCreated = true;
    row.m_ppMatrix = m_ppMatrix;
    row.m_nXSize   = m_nXSize;
}

template<class T>
CMatrix<T>::CMatrix(const CMatrix& matrix)
{
    m_nXSize = matrix.m_nXSize;
    m_nYSize = matrix.m_nYSize;
    m_nMemorySize = m_nYSize*m_nXSize*sizeof(T);

    m_ppMatrix    = new T* [m_nYSize];
    ASSERT(m_ppMatrix!=NULL);

    m_ppMatrix[0] = new T  [m_nYSize*m_nXSize];
    ASSERT(m_ppMatrix[0]!=NULL);

    for (int i=1; i<m_nYSize; i++)
        m_ppMatrix[i] = m_ppMatrix[0]+i*m_nXSize;

    memcpy(m_ppMatrix[0],matrix.m_ppMatrix[0], m_nMemorySize);

    m_bCreated = true;
}


template<class T>
CMatrix<T>& CMatrix<T>::operator= (const CMatrix& matrix)
{
    if (this == &matrix) return *this;

    ASSERT(m_nXSize == matrix.m_nXSize && 
        m_nYSize == matrix.m_nYSize);
    memcpy(m_ppMatrix[0],matrix.m_ppMatrix[0], m_nMemorySize);

    return *this;
}
template<class T>
T CMatrix<T>::GetMinValue()
{
    T minValue = m_ppMatrix[0][0];
    int i,j;

    for (i=0; i<m_nYSize; i++)
        for (j=0; j<m_nXSize; j++)
        {
            if(m_ppMatrix[i][j]<minValue)
                minValue = m_ppMatrix[i][j];
        }
        return minValue;
}

template<class T>
T CMatrix<T>::GetMaxValue()
{
    T maxValue = m_ppMatrix[0][0];
    int i,j;

    for (i=0; i<m_nYSize; i++)
        for (j=0; j<m_nXSize; j++)
        {
            if(m_ppMatrix[i][j]>maxValue)
                maxValue = m_ppMatrix[i][j];
        }
        return maxValue;
}

template<class T>
CMatrix<T> CMatrix<T>::operator+ (const T& item)
{
    int i, j;

    CMatrix<T> mtrx(m_nYSize, m_nXSize);
    for (i=0; i<m_nYSize; i++)
        for (j=0; j<m_nXSize; j++)
        {
            mtrx.m_ppMatrix[i][j] = m_ppMatrix[i][j]+item ;
        }
        return mtrx;
}

template<class T>
CMatrix<T> CMatrix<T>::operator- (const T& item)
{
    int i, j;

    CMatrix<T> mtrx(m_nYSize, m_nXSize);
    for (i=0; i<m_nYSize; i++)
        for (j=0; j<m_nXSize; j++)
        {
            mtrx.m_ppMatrix[i][j] = m_ppMatrix[i][j]-item ;
        }
        return mtrx;
}

template<class T>
CMatrix<T>::~CMatrix()
{
    if (m_bCreated)
    {
        delete [] m_ppMatrix[0];
        delete [] m_ppMatrix;
    }
}

template<class T>
int CMatrix<T>::GetXSize()
{
    return m_nXSize;
}

template<class T>
T CMatrix<T>::SumAll()
{
    T sum = 0;
    int i, j;

    for (i=0; i<m_nYSize; i++)
        for (j=0; j<m_nXSize; j++)
        {
            sum += m_ppMatrix[i][j];
        }
        return sum;
}

template<class T>
int CMatrix<T>::GetYSize()
{
    return m_nYSize;
}
template<class T>        //Y(row) X(col)      
T& CMatrix<T>::operator()(int i, int j)
{
    ASSERT(i>=0 && i<m_nYSize &&
        j>=0 && j<m_nXSize);

    return m_ppMatrix[i][j];
}

//Fancy Indexing
template<class T> 
Container2DRow<T> CMatrix<T>::operator [] (int i)
{
    ASSERT(i>=0 && i<m_nYSize); 
    row.i = i;
    return row;
}

template<class T> 
const Container2DRow<T> CMatrix<T>::operator [] (int i) const
{
    ASSERT(i>=0 && i<m_nYSize); 
    row.i = i;
    return row;
}

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

About the Author

Alex Chirokov
Researcher
United States United States
Member
I mostly work with implementation and development of numerical methods in C#, C/C++ and Fortran. I tried many different languages like Pascal, Delphi, Basic, Java, Python, Perl but C++ is still my favorite.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generalnice articlememberlxz20889 May '06 - 23:03 
i am studting in image processing,and The article help me
GeneralContainer loading heuristic algorithmmemberrajeshdara25 Mar '06 - 6:32 
hi
i have a project can u implement this
 
Hi,
My question is
I have to develop an application where to fill the i rectangular boxes of different sizes in similar containers where 85% volume should be utilised . procedure is
1.user should enter the values like length,breadth , height of N rectangular boxes
2.First thing is our program should select some boxes randomly and try to fit in container,. try all the possible combinations of all boxes so that maximum volume used.once best combination reached,replicate combination to other container as all containers has same size and try to fit in the container.
3.Repeat the same step for remaining boxes and try to fill all the boxes in M containers
4.Filling the boxes in container we can use any approach.
5.output should be 3D Grapical containers where position of each box is shown
for example
if 7th container has box no 23 ,29 63 ,79
output should be in 3D with exact location of each boxe in the container should be shown
 
IMPORTANT THING IS U HAVE FREEDOM TO USE ANY SOFTWARE
 
rajeshdara@gmail.com
GeneralRow and Colsmemberschnufftrax5 Jan '05 - 21:55 
How can i access rows and cols with this class.
What I need is this:
 
Matrix(x,x) m;
 
vector x = m.row();
vector y = m.col();
Generaloperator[]memberBheadlim22 Oct '04 - 2:54 
template<class T>
const T& Container2DRow<T>::operator [] (int j) const
{
      cout << " ---=> with const " << endl;
      assert(j>=0 && j<m_nXSize);
      return m_ppMatrix[i][j];
}
 
template<class T>
T& Container2DRow<T>::operator [] (int j)
{
      cout << " ---=>without const " << endl;
      assert(j>=0 && j<m_nXSize);
      return m_ppMatrix[i][j];
}
 
i found that the program never call the one with const, can someone tell me how to force it in my main program??
 
int main()
{
     CMatrix<int> a(2,2);
     a[0][0] = 99;
     cout << " Finished assign value to a[0][0] " << endl;
     cout << "a[0][0] is " << a[0][0] << endl;
     cout << " Finish couting.. " << endl;
     int a_integer = a[0][0];
     cout << " Finished assign value to a_integer " << endl;
     cout << " a_integer is " << a_integer << endl;
     return 0;
}
GeneralRe: operator[]memberAlex Chirokov31 Oct '04 - 11:35 
int main()
{
CMatrix a(2,2);
a[0][0] = 99;
cout << " Finished assign value to a[0][0] " << endl;
cout << "a[0][0] is " << a[0][0] << endl;
cout << " Finish couting.. " << endl;
int a_integer = a[0][0];
 
//creating constant matrix b
const CMatrix b(a);
 
//This will call const operator
cout << " Calling const operator " << endl;
cout << " b[0][0] " << b[0][0]<< endl;

//Without const operators there will be no way of accessing elements of const matrix
return 0;
}
 

 
/*
Alex-
*/
GeneralVisual C++ (MFC) : Using Matrix to set an part of an image to zeromemberpohcb_sonic15 Sep '04 - 16:36 
Hi! I'm new to MFC in Visual C++ programming. I had previously used it to do console applications but never used MFC before. I had a problem; I was told to set a 4 by 4 area by using Matrix in MFC coding and use it to check whether the image has any little "black spots". If it does, I have to set these small little "black spots" of the image from "255" or anything else to zero.
 
So How do I do it?
 
Pls do kindly reply. I needed this asap. Thanks!
Smile | :)
 
Ps: here are all my codings:
 

 
// MediVisionView.cpp : implementation of the CMediVisionView class
//
 
#include "stdafx.h"
#include "MediVision.h"
#include "PatientDialogBox.h"
#include "MediVisionDoc.h"
#include "MediVisionView.h"
#include "Glob.h"
#include "Math.h"
#include "Edit_Patient_Data.h"
#include "Expand_Pixel.h"
#include "Rows_Cols.h"
 
#include
#include
 
typedef std::vector StringArray; //typedef vector of string type
using namespace std; //do not need to prepend std:: to Standard Library
 

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
 
unsigned char *argbPixelsPtr;
unsigned char *rgbPixelsPtr;
unsigned int argbPixels[512][512];
unsigned int argb256Pixels[256][256];
unsigned int rgbPixels[512][512];
unsigned int rgb256Pixels[256][256];
unsigned int storeargbPixels[512][512];
 

int *Bitmap_r, *Bitmap_g, *Bitmap_b;
int *image[5], *store[5], *image256, *store256, *image512, *store512, *image32, *store32,*image16, *store16;
int mouse1_x, mouse1_y, mouse2_x, mouse2_y; //Store mousedown and mouseup coordinate (For rectangle)
int rows1,rows2,cols1,cols2;
int clk_mouse_x, clk_mouse_y; //Store reference point wrt to the screen left hand corner
int ref_selected_x, ref_selected_y; //Store the computed reference point wrt to the image left hand corner
int ref_intensity; //Store Reference point intensity (for region growing) value
int Grad_x, Grad_y, Grad_z; //For storing Gradient values during volume rendering
 

short dcmPixel[480][262144];
 

float alphaTable[262144];
float luminanceTable[262144];
float MidX, MidY, MidZ;
float Translation[4][4];
float Rotation[4][4];
float pt_x[5], pt_y[5], pt_z[5];
 

char UID[30];
 

int *pixelvalue, maxpix;
int box_x, box_y; // Co-ordinates of the top left hand corner of box with reference to image corner.
CDC *pDC;
HDC hdc;
int n_rows, n_cols;
int k = 0;
int Expand_Pixel;
int s, nCount;
 

CString strAppDirectory;
long position, sliceThickness_position,ImageNo_position,Axis_position,PixelSize_position;
int ** region;
int pass; // Number of times that ReadFile module is called
// This is use for deleted the pointers as we want
bool insert, rightbut;
// do not want to delete the last set of image data of 3D maximum intensity option
bool noFile, Flag3D; // Flag3D is a flag to indicate that the 3D maximum intensity option is selected
bool box, ref_pt; //<------------------------
 

// camera function
int magnification;
bool zoom, grid;
 
bool eraser, leftbut;
bool multiple_open;
bool cancel1,cancel2;
CPoint er_point;
CPoint Anchor;
FILE *fp, *fw, *fe; // File pointer
 
char *st;
 
bool edited;
void SetClassificationTable();
void DrawRectn();
 
////////////////////////////Modified Variables(For Object Lining Menu)////////////////////////////////////
//-----------New coding-------------//
bool Rectn; //To define the Rectangular box item created.
 
//int m1_x, m1_y, m2_x, m2_y; //Store mousedown and mouseup coordinate (For Rectangular box)
 
int mouse_x, mouse_y; //Store reference point with correspond to the screen left hand corner
 
int num; // number
 
int r, c; //rows and column of Rectangular Box
 
int max, min; //maximum and minimum of image
 
int point_x, point_y; //Define the points inside the image
 
int point_x1, point_y1; //Define the points inside the image
 
int point_w1, point_z1;
 
bool minflag, maxflag;
 
int sg_length, sg_height; // Length and height of the Rectangular box
 
/////////////////////////////////////////////////////////////////////////////
//--------------End of coding-----------------//
 
// CMediVisionView
 
IMPLEMENT_DYNCREATE(CMediVisionView, CView)
BEGIN_MESSAGE_MAP(CMediVisionView, CView)
//{{AFX_MSG_MAP(CMediVisionView)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_WM_ERASEBKGND()
ON_COMMAND(ID_3D_MAXIMUMINTENSITY, On3dMaximumintensity)
ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
ON_COMMAND(ID_3D_SURFACERENDERING, On3dSurfacerendering)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_COMMAND(ID_SEGMENTATION_REGIONGROWING, OnSegmentationRegiongrowing)
ON_WM_SETCURSOR()
ON_COMMAND(ID_FILE_MULTIPLEOPEN, OnFileMultipleopen)
ON_COMMAND(ID_RToolbar_3DIntensity, OnRToolbar3DIntensity)
ON_COMMAND(ID_RToolbar_Multipleopen, OnRToolbarMultipleopen)
ON_COMMAND(ID_RToolbar2_Region, OnRToolbar2Region)
ON_COMMAND(ID_3D_VOLUMERENDERING, On3dVolumerendering)
ON_COMMAND(ID_TOOLS_ERASER, OnToolsEraser)
ON_COMMAND(ID_TOOLS_BOOLEAN, OnToolsBoolean)
ON_COMMAND(ID_TOOLS_MAXIMATION, OnToolsMaximation)
ON_COMMAND(ID_ERASER, OnEraser)
ON_COMMAND(ID_TOOLS_PEN, OnToolsPen)
ON_COMMAND(ID_PEN, OnPen)
ON_COMMAND(ID_EDIT_PATIENT_DATA, OnEditPatientData)
ON_COMMAND(ID_MORPHOLOFICAL, OnMorpholofical)
ON_COMMAND(ID_ZOOM_2X, OnZoom2x)
ON_COMMAND(ID_ZOOM_4X, OnZoom4x)
ON_COMMAND(ID_TOOLS_EXPANSION, OnToolsExpansion)
ON_COMMAND(ID_LINE_OBJECTS, OnLineObjects)
ON_WM_RBUTTONDOWN()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
 
/////////////////////////////////////////////////////////////////////////////
// CMediVisionView construction/destruction
 
CMediVisionView::CMediVisionView()
{
// TODO: add construction code here
m_File1 = _T(" ");
pixelmax = 256;
maxpix = 256;
multiple_open = false;
no_of_rows = 0;
no_of_cols = 0;
box = false;
eraser = false;
leftbut = false;
ref_pt = false;
MotionFix = 0;
m_Dragging = false;
Expand_Pixel = 0;

 
//-------------New Coding----------------//
Rectn = false; // Disables the drawing of the rectangle
MDrag = false; //Disables the Dragging of the mouse
Motion = 0; //Set the motion of the mouse to draw rectangle to none
mini = 0;
maxi=0;
 
//---------------End of coding-------------//
 

 
}
 
CMediVisionView::~CMediVisionView()
{
// delete [] region;
}
 
BOOL CMediVisionView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
 
return CView::PreCreateWindow(cs);
}
 
/////////////////////////////////////////////////////////////////////////////
// CMediVisionView drawing
 

void FrameLines(CDC *pDC) {
 
// CPen newPen(PS_SOLID,pixelsize, colour);
// CPen* pOldPen = pDC->SelectObject(&newPen);
// pDC->MoveTo(x,y); // move current position of pen
// pDC->LineTo(x+1,y+1);
// pDC->SelectObject(pOldPen);// reset back the old pen object
 
CBrush brush, *pOB;
 
int xSize=::GetSystemMetrics(SM_CXSCREEN);
int ySize=::GetSystemMetrics(SM_CYSCREEN);
 
brush.CreateSolidBrush(RGB(210,220,205));
pOB = pDC->SelectObject(&brush);
 
pDC->Rectangle(525, -1, 530, ySize);
pDC->Rectangle(529, (ySize/2 - 45), xSize, (ySize/2-40));
}
 

 
void CMediVisionView::OnDraw(CDC* pDC)
{
CMediVisionDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
 

if (First==TRUE) {
First=FALSE;
Draw(); // If it is the first time, use draw
CClientDC ClientDC(this);
FrameLines(&ClientDC);

}
else {
ReDraw(); // To redraw
}
}
 
void DrawBox(CDC *pdc,CPoint m_One, CPoint m_Two)
{
pdc->MoveTo(m_One);
pdc->LineTo(m_One.x, m_Two.y);
 
pdc->MoveTo(m_One);
pdc->LineTo(m_Two.x, m_One.y);
 
pdc->MoveTo(m_Two.x,m_One.y);
pdc->LineTo(m_Two.x, m_Two.y);
 
pdc->MoveTo(m_One.x,m_Two.y);
pdc->LineTo(m_Two.x, m_Two.y);

}
 
/////////////////////////////////////////////////////////////////////////////
// CMediVisionView printing
 
BOOL CMediVisionView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
 
void CMediVisionView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
 
void CMediVisionView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
 
/////////////////////////////////////////////////////////////////////////////
// CMediVisionView diagnostics
 
#ifdef _DEBUG
void CMediVisionView::AssertValid() const
{
CView::AssertValid();
}
 
void CMediVisionView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
 
CMediVisionDoc* CMediVisionView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMediVisionDoc)));
return (CMediVisionDoc*)m_pDocument;
}
#endif //_DEBUG
 
/////////////////////////////////////////////////////////////////////////////
 
/* This routine(onFileOpen) is use for opening only 1 selected file.
It will call ReadFile to read the Dicom file and display it.*/
 
////////////////////////////////////////////////////////////////////////////
CString file;
 
void CMediVisionView::OnFileOpen()
{
 
// TODO: Add your command handler code here
 
// static char BASED_CODE szFilter[] = "All Files (*.*)|*.*|Bitmap Files(*.bmp)| *.bmp|\
// DICOM Files(*.dcm) | *.dcm";
multiple_open=false;
image_no=0;
OpenFile();
}
 
////////////////////////////////////////////////////////////////////
/* These routines OnInitial Update to OnEraseBkgnd is
used topaint the background Blue */
///////////////////////////////////////////////////////////////////
 
void CMediVisionView::OnInitialUpdate()
{
CView::OnInitialUpdate();

// TODO: Add your specialized code here and/or call the base class
SetBackgroundColor(RGB(50, 50, 50));
CMediVisionDoc* pDoc = GetDocument();
pDoc->SetPathName("LEO",TRUE);
}
 
void CMediVisionView::SetBackgroundColor(COLORREF crBackground)
{
m_crBackground = crBackground;
if (m_wndbkBrush.GetSafeHandle())
m_wndbkBrush.DeleteObject();
m_wndbkBrush.CreateSolidBrush(m_crBackground);
}
 

BOOL CMediVisionView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
CRect rect;
GetClientRect(rect);
pDC->FillRect(&rect, &m_wndbkBrush);
return TRUE;
 
}
 
/////////////////////////////////////////////////////////////////////
/* This routine ReDraw is use to refresh the screen after minimise.
The routine differentiates drawing of 512x512 or 256x256 image data
For 256x256, it allows multiple images to be screen. For 512x512,
only 1 image is shown. This routine is called by OnDraw(). */
////////////////////////////////////////////////////////////////////
 
void CMediVisionView::ReDraw()
{
int row, col;
int p, q, n;
int cx_position[6], cy_position[6];
unsigned int data;
 
BITMAPINFOHEADER infoHeader;
infoHeader.biSize = sizeof(BITMAPINFOHEADER);
infoHeader.biWidth = n_cols;
infoHeader.biHeight = n_rows;
infoHeader.biPlanes=1;
infoHeader.biBitCount= 24;
infoHeader.biCompression=0;
infoHeader.biSizeImage=0;
infoHeader.biXPelsPerMeter=0;
infoHeader.biYPelsPerMeter=0;
infoHeader.biClrUsed=0;
infoHeader.biClrImportant=0;
 
int xSize=::GetSystemMetrics(SM_CXSCREEN)-80;
int ySize=::GetSystemMetrics(SM_CYSCREEN);
 
CClientDC ClientDC(this); // Draw the Frame Lines first
FrameLines(&ClientDC);
 
if (n_rows== 256 && multiple_open) {
if(image_no == 1) {
cx_position[1] = ((xSize/2) - (n_cols/2));
cy_position[1] = ((ySize/2) - (n_rows/2)) - 70;
}
else if(image_no == 2) {
cx_position[1] = ((xSize/2) - (n_cols+10));
cy_position[1] = ((ySize/2) - (n_rows/2)) - 70;
cx_position[2] = ((xSize/2) + 10);
cy_position[2] = ((ySize/2) - (n_rows/2)) - 70;
}
else if(image_no == 3) {
cx_position[1] = 5;
cy_position[1] = ((ySize/2) - (n_rows/2)) - 70;
cx_position[2] = 5 + n_cols + 5;
cy_position[2] = ((ySize/2) - (n_rows/2)) - 70;
cx_position[3] = 5 + n_cols + 5 + n_cols + 5;
cy_position[3] = ((ySize/2) - (n_rows/2)) - 70;
}
else if(image_no == 4) {
cx_position[1] = ((xSize/2) - (n_cols+20));
cy_position[1] = ((ySize/2) - (n_rows+20)) - 50;
cx_position[2] = ((xSize/2) +20);
cy_position[2] = ((ySize/2) - (n_rows+20)) - 50;
cx_position[3] = ((xSize/2) - (n_cols+20));
cy_position[3] = ((ySize/2) +10) - 70;
cx_position[4] = ((xSize/2) +20);
cy_position[4] = ((ySize/2) +10) - 70;
}

for(int s=1;s<=image_no;s++) {
n = 0;
for(int p=0;pGetSafeHdc();
// Draw();
 
if (Flag3D == true) {
delete [] pixelvalue;
if (pass < nCount) {
if (n_rows == 512) {
delete [] image512; // Delete storage due to reptitive creation in the 3Dmaximum intensity
delete [] store512;
}
else if (n_rows == 256 && !multiple_open) {
delete [] image256; // Only the first image array parameter was used for 3D display, so delete it
delete [] store256;
}
else if (n_rows == 256 && multiple_open) {
delete [] image[image_no];
delete [] store[image_no];
}
}
}
 
} while(pos);

}
 
if (no_of_rows==256) {
image256=new int [no_of_rows*no_of_cols]; // Creating memory for storing an array of image data
store256=new int [no_of_rows*no_of_cols];
}
else {
image512 = new int [no_of_rows*no_of_cols];
store512 = new int [no_of_rows*no_of_cols];
}
 
Compute_Vol_Max_Intensity();
Invalidate(); //refresh window
UpdateWindow();
pDC = GetDC();
hdc=pDC->GetSafeHdc();
Draw();
 
}
}
 
void CMediVisionView::ReadFile()
{
 
int i, loop, n, p,q;
short tag[2];
long num;
char a;
char VR[2], DICM[5], *string;//, *pixel_size;
int iLength;
short ValueLength;
short ValueField;
short ReservedField; // For OB, OW, SQ and UN data type only
unsigned short sdata;
unsigned int idata;
bool flag, pixelread;
 
// if ((fw = fopen(strAppDirectory + "\\test.dcm","w+b")) == NULL)
if ((fw = fopen("test.dcm","w+b")) == NULL)
AfxMessageBox("Cannot open binary file for some reason");
 
if (noFile == false) {
flag = true;
pixelread = true;
pixelmax = 256;
n=0;
fseek(fp, 128, 0); // Skip 128 Bytes
fseek(fw, 128, 0);
fgets(DICM,5,fp);
 
//--READING OF TAGS IN DICOM FILE ------------------------------------
 
if (strcmp(DICM, "DICM")!=0) { // Not the latest DICM file
fseek(fp, 0, 0); // Push the File pointer to the beginning of file
fseek(fw, 0, 0);
string=new char[20]; // For deletion purpose
strcpy(UID, "1.2.840.10008.1.2");
}
else
fwrite(DICM, sizeof(char), 4, fw);
 
while (flag == true) {
for (i=0; i<2;i++) { // Read Tag - 2 bytes
fread(&tag[i], sizeof(unsigned short), 1, fp); // Ordered pair of 16-bit unsigned int
fwrite(&tag[i], sizeof(unsigned short), 1, fw);
}
 
//--READING AND WRITING DATA ELEMENT OF HEADER FOR SAVING------------------------------------

if (tag[0] < 32736) {
if (tag[0]==2) { // For tag 2 only
strcpy(VR, " ");
fgets(VR,3,fp); // Read Value Representation
fwrite(VR, sizeof(char), 2, fw);
 
if (tag[1]==16) { // Read the Transfer Syntax data UID
fread(&ValueLength, sizeof(unsigned short), 1, fp); // Read Value Length (VL) - 16 bits
fwrite(&ValueLength, sizeof(unsigned short), 1, fw);
 
fgets(UID,ValueLength+1,fp);
fwrite(UID, sizeof(char), ValueLength, fw);
}
else {
if (strcmp(VR, "UL")==0) {
fread(&ValueLength, sizeof(unsigned short), 1, fp); // Read Value Length (VL) - 16 bits
fwrite(&ValueLength, sizeof(unsigned short), 1, fw);
fread(&ValueField, sizeof(unsigned long), 1, fp); // Read Value Field (4 bytes as indicated by VL)
fwrite(&ValueField, sizeof(unsigned long), 1, fw);
}
 
else if (strcmp(VR,"OB")==0) {
fread(&ReservedField, sizeof(unsigned short), 1, fp);// Read Reserved Field
fwrite(&ReservedField, sizeof(unsigned short), 1, fw);
fread(&ValueLength, sizeof(unsigned short), 1, fp); // Read Value Length (VL) - 16 bits
fwrite(&ValueLength, sizeof(unsigned short), 1, fw);
fread(&ValueField, sizeof(unsigned long), 1, fp); // Value Field (4 bytes as indicated by VL)
fwrite(&ValueField, sizeof(unsigned long), 1, fw);
}
 
else if (strcmp(VR, "UI")==0 || strcmp(VR, "SH")==0 || strcmp(VR, "AE")==0) {
fread(&ValueLength, sizeof(unsigned short), 1, fp); // Read Value Length (VL) - 16 bits
fwrite(&ValueLength, sizeof(unsigned short), 1, fw);
string=new char[ValueLength+1];
fgets(string,ValueLength+1,fp);
fwrite(string, sizeof(char),ValueLength,fw);
}
 
else { // Read Implicit CS
num = (int)VR[0];
fgetc(fp);

for (loop=0; loop5000)
sdata = 0; // pixel data too large, probably due to noise
pixelmax = (sdata > pixelmax)? sdata : pixelmax;
maxpix = pixelmax;
pixelvalue[n] = sdata;

n++; // Increment the reading by 1
 
if (n==(no_of_rows*no_of_cols)) // if finish reading the pixel data
pixelread=false;
}
 
flag=false;
}
} // end of while loop

fclose (fp);
}
 

n=0;
for (p=0; p image256[i] ? dcmPixel[j][i] : image256[i]);
store256[i] = image256[i];
}
}
}
else {
for(i=0;i 0) {
image512[i] =
(dcmPixel[j][i] > image512[i] ? dcmPixel[j][i] : image512[i]);
store512[i]=image512[i];
}

}
}
}
 
//---------------------------------------------------------------
/*
pt_x[2] = (float)(n_rows-1)/2.0; // Compute the centriod of volume data
pt_y[2] = (float)(n_cols-1)/2.0;
pt_z[2] = (float)(nCount-1)/2.0;

float *view_x_plane = new float[n_rows*n_cols]; // create view plane;
float *view_y_plane = new float[n_rows*n_cols];
float *view_z_plane = new float[n_rows*n_cols];
float *Translate_x = new float[n_rows*n_cols];
float *Translate_y = new float[n_rows*n_cols];
float *Translate_z = new float[n_rows*n_cols];
 
// Generate the co-ordinates of the viewing plane
 
x1 = 0;
y1 = n_rows-1;
 
for (point_no=0; point_no10) {
image256[i] = dcmPixel[j][i];
store256[i] = image256[i];
break;
}
}
}
}
 
else {
 
j=0;
for(i=0;i0) {
image512[i] = dcmPixel[j][i];
store512[i] = image512[i];
break;
}
}
}
}
pDC = GetDC();
hdc=pDC->GetSafeHdc();
Draw();
return;
}
 
void CMediVisionView::OnLButtonDown(UINT nFlags, CPoint point)
{


// TODO: Add your message handler code here and/or call default
if (box) {
m_PointOrigin = point;
mouse1_x = point.x;
mouse1_y = point.y;
m_Dragging = true;

}
 
if (ref_pt && !box) { // If the mouse is press down set click
ref_pt = false;
clk_mouse_x = point.x; // Find the reference point position
clk_mouse_y = point.y;
Segment_Region();// Segmentation is called only after reference pt has been selected

}
 
//----------------------New coding-------------------------------------//
//when left Button of the Mouse is pressed down//
 
if (Rectn) { //Rectn is true

m_PO = point; //Assign co-ordinates to m_PO
m1_x = point.x; //Assign co-ordinate x to m1_x
m1_y = point.y; //Assign Co-ordinate y to m1_y
MDrag = true; //Activates Dragging of the rectangular box by the mouse
 
}
 
if (!Rectn) { // If not Rectn, the mouse is pressed down and set click!
//Disables the reference point
mouse_x = point.x; // Find the reference point position
mouse_y = point.y;


}

//--------------------------------------------------------------------//
 

if(eraser==true) { //if eraser is selected
leftbut=true;
}
 
if(insert==true) //if insert is selected
{
rightbut=true;
}
 
CView::OnLButtonDown(nFlags, point);
}
 
void CMediVisionView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (m_Dragging) {
mouse2_x = point.x;
mouse2_y = point.y;
 
box = false;
m_Dragging = false;
MotionFix=0;
ref_pt = true; // Set the reference point flag is true only box has been drawn
}
 

//----------------------------------New Coding---------------------------------//
//When left button of the mouse is released//
if (MDrag) {
//m2_x = point.x; //assign the coordinate of position x clicked by mouse to point x
//m2_y = point.y; //assign the coordinate of position y clicked by mouse to point y

Rectn = false; //disables drawing of rectangle
MDrag = false; //disables Mouse dragging
Motion =0; //set the motion of the mouse to draw the rectangle to none
AreaSegmentation(); // Area Segmentation( ) is called when reference point has been selected
MessageBox("Pls Right-Click to find the minimum point WITHIN the box!!");
minflag = true; //Right-click to set the minimum point within the rectangle box
}
 
//-----------------------------------------------------------------------------//


zoom = false;
leftbut = false;
 
eraser = false;
leftbut = false;
insert = false;
rightbut = false;
 

CView::OnLButtonUp(nFlags, point);
}
 
void CMediVisionView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
int cur_pos_x, cur_pos_y;
int n;
 
if(eraser==true) { // For erasing only
if(leftbut==true){
er_point = point;

cur_pos_x = er_point.x - posx512; // Compute the current eraser point position
cur_pos_y = er_point.y - posy512;
n = (512-(cur_pos_y))*512 + cur_pos_x; // Translate it to the image pixel n
 
for (int i=0; i<7; i++) {
image512[n+i] = 0; // Delete for 7 pixels horizontal
image512[(n-512)+i] =0; // Delete 2nd rows each time
image512[(n-512*2)+i]=0; // Delete 3rd row also
image512[(n-512*3)+i]=0;
image512[(n-512*4)+i]=0;
image512[(n-512*5)+i]=0;
image512[(n-512*6)+i]=0;
 
store512[n+i] = 0;
store512[(n-512)+i] = 0;
store512[(n-512*2)+i] = 0;
store512[(n-512*3)+i] = 0;
store512[(n-512*4)+i] = 0;
store512[(n-512*5)+i] = 0;
store512[(n-512*6)+i] = 0;
 
}

pDC = GetDC();
hdc=pDC->GetSafeHdc();

Draw();
}
}
/*else */if(insert==true) // For pen only
{
if(rightbut==true)
{
// pen for image size 256 by 256
if (no_of_rows == 256)
{
er_point = point;

cur_pos_x = er_point.x - posx256; // Compute the current eraser point position
cur_pos_y = er_point.y - posy256;
n = (256-(cur_pos_y))*256 + cur_pos_x; // Translate it to the image pixel n
 
for (int i=0; i<2; i++)
{
image256[n+i] = 255; // Delete for 2 pixels horizontal
image256[(n-256)+i] =255; // Delete 2nd rows each time
// image256[(n-256*2)+i]=255; // Delete 3rd row also
// image256[(n-256*3)+i]=255;
// image256[(n-256*4)+i]=255;
// image256[(n-256*5)+i]=255;
// image256[(n-256*6)+i]=255;
 
store256[n+i] = 255;
store256[(n-256)+i] = 255;
// store256[(n-256*2)+i] = 255;
// store256[(n-256*3)+i] = 255;
// store256[(n-256*4)+i] = 255;
// store256[(n-256*5)+i] = 255;
// store256[(n-256*6)+i] = 255;
}
}
 
// pen for image size 512 by 512
if (no_of_rows == 512)
{
er_point = point;

cur_pos_x = er_point.x - posx512; // Compute the current eraser point position
cur_pos_y = er_point.y - posy512;
n = (512-(cur_pos_y))*512 + cur_pos_x; // Translate it to the image pixel n
 
for (int i=0; i<10; i++)
{
image512[n+i] = 255; // Delete for 2 pixels horizontal
image512[(n-512)+i] =255; // Delete 2nd rows each time
image512[(n-512*2)+i]=255; // Delete 3rd row also
image512[(n-512*3)+i]=255;
image512[(n-512*4)+i]=255;
image512[(n-512*5)+i]=255;
image512[(n-512*6)+i]=255;
image512[(n-512*7)+i]=255;
image512[(n-512*8)+i]=255;
image512[(n-512*9)+i]=255;
 

store512[n+i] = 255;
store512[(n-512)+i] = 255;
store512[(n-512*2)+i] = 255;
store512[(n-512*3)+i] = 255;
store512[(n-512*4)+i] = 255;
store512[(n-512*5)+i] = 255;
store512[(n-512*6)+i] = 255;
store512[(n-512*7)+i] = 255;
store512[(n-512*8)+i] = 255;
store512[(n-512*9)+i] = 255;
 
}
}


pDC = GetDC();
hdc=pDC->GetSafeHdc();

Draw();
}
}
 
if (zoom == true) // for zoom only
{
//if (leftbut == true)
{

// do if, if image size is 256 by 256
if (no_of_rows == 256)
{
 

er_point = point;

cur_pos_x = er_point.x - posx256; // Compute the current mouse point position
cur_pos_y = er_point.y - posy256;
 
Draw_Zoom(cur_pos_x, cur_pos_y);
 
}
 

// do if, if image size is 512 by 512
if (no_of_rows == 512)
{
 

er_point = point;

cur_pos_x = er_point.x - posx512; // Compute the current mouse point position
cur_pos_y = er_point.y - posy512;
 
Draw_Zoom(cur_pos_x, cur_pos_y);
 

}
 
pDC = GetDC();
hdc=pDC->GetSafeHdc();

Draw();

CClientDC zoomDC(this);
zoomDC.SetROP2(R2_NOTXORPEN);
// draw the lines at the exact mouse position
DrawZoomBox(&zoomDC, cur_pos_x, cur_pos_y);
//ClientDC.Rectangle((point.x + 35), (point.y + 35), (point.x - 35), (point.y - 35));

}
 

}
 

if (m_Dragging && m_PointOrigin!=point ) {
 
CClientDC ClientDC (this);
mouse2_x = point.x;
mouse2_y = point.y;

ClientDC.SetROP2(R2_NOTXORPEN); //R2_NOTXORPEN Pixel is the inverse of the R2_XORPEN color.
 
if (MotionFix) DrawBox(&ClientDC,m_PointOrigin,m_PointOld);
MotionFix++;
 
DrawBox(&ClientDC,m_PointOrigin,point);
}
 
m_PointOld = point;
 

//-------------New Coding----------------------//
 
if (MDrag && m_PO!=point) { //For dragging onto a point by using the mouse

Rectn= true;
CClientDC FDC (this);
m2_x = point.x;
m2_y = point.y;

FDC.SetROP2(R2_NOTXORPEN); //highlights the image//
 
if (Motion) DrawRectn(&FDC, m_PO, m_OldPO); //happens when Motion is not 0.
Motion++;



DrawRectn(&FDC,m_PO,point);


}
 
m_OldPO = point;
 
//---------------------------------------------//
 

 

CView::OnMouseMove(nFlags, point);
}
 

void CMediVisionView::DrawZoomBox(CDC *pdc, int mouse_x, int mouse_y)
{
int half_box_length;
 
half_box_length = (ZOOM_BOX / 2);
 
if (no_of_rows == 512)
{
// if mouse pointer is within range of image
if (((mouse_x-half_box_length) > 0) && ((mouse_x+half_box_length) < no_of_rows) && ((mouse_y-half_box_length) > 0) && ((mouse_y+half_box_length) < no_of_rows))
{
 
CPoint top_left;
CPoint bottom_right;
 
top_left.x = mouse_x-(half_box_length)+10;
top_left.y = mouse_y-(half_box_length)+10;
bottom_right.x = mouse_x+(half_box_length)+10;
bottom_right.y = mouse_y+(half_box_length)+10;
 
pdc->MoveTo(top_left); // start at top left corner
pdc->LineTo(top_left.x+ZOOM_BOX, top_left.y); // draw line to the right
pdc->LineTo(bottom_right); // then draw line downwards to bottom right corner
 
pdc->MoveTo(bottom_right); // now start from bottom right corner
pdc->LineTo(bottom_right.x-ZOOM_BOX, bottom_right.y); // draw line to the left
pdc->LineTo(top_left); // then draw line upwards to top left corner
 
if (grid == true)
{
 
}
}
 
}
 
}
 

void CMediVisionView::Draw_Zoom(int mx, int my)
{
 
// to zoom image when zoom is activated and mouse move over image
int ref=0, r=0, c=0, n=0, m=0;
 
int row=0, col=0;
//int p, q;
//int cx_position[6], cy_position[6];
unsigned int data=0;
 

int zoom_rows = ZOOM_BOX;
int zoom_cols = ZOOM_BOX;

// zoom for image size 256 by 256
if(n_rows==256)
{
// StretchBlt(hdc, posxZOOM,posyZOOM, zoom_rows*8, zoom_cols*8, hdc, ((mx-(ZOOM_BOX/2))), ((my-(ZOOM_BOX/2))), (zoom_rows+(ZOOM_BOX/2)), (zoom_cols+(ZOOM_BOX/2)), SRCCOPY);
StretchBlt(hdc, posxZOOM,posyZOOM, zoom_rows*magnification, zoom_cols*magnification, hdc, ((mx-(ZOOM_BOX/2))+10), ((my-(ZOOM_BOX/2))+10), zoom_rows, zoom_cols, SRCCOPY); // +10 to offset 10 pix by 10 pix
 
}
 

// zoom for image size 512 by 512
if(n_rows==512)
{
// StretchBlt(hdc, posxZOOM,posyZOOM, zoom_rows*8, zoom_cols*8, hdc, ((mx-(ZOOM_BOX/2))), ((my-(ZOOM_BOX/2))), (zoom_rows+(ZOOM_BOX/2)), (zoom_cols+(ZOOM_BOX/2)), SRCCOPY);
StretchBlt(hdc, posxZOOM,posyZOOM, zoom_rows*magnification, zoom_cols*magnification, hdc, ((mx-(ZOOM_BOX/2))+10), ((my-(ZOOM_BOX/2))+10), zoom_rows, zoom_cols, SRCCOPY); // +10 to offset 10 pix by 10 pix
}
 
}
 
void CMediVisionView::OnZoom2x()
{
// TODO: Add your command handler code here
 
image32 = new int [ZOOM_BOX * ZOOM_BOX];
 
magnification = 2;
 
if (!zoom) // toggle zoom on/off
zoom = true;
else
zoom = false;
 

}
 
void CMediVisionView::OnZoom4x()
{
// TODO: Add your command handler code here

image32 = new int [ZOOM_BOX * ZOOM_BOX];
 
magnification = 4;
 
if (!zoom) // toggle zoom on/off
zoom = true;
else
zoom = false;


}
 
void CMediVisionView::OnSegmentationRegiongrowing()
{
// TODO: Add your command handler code here
box = true;
}
 
BOOL CMediVisionView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
 
if(box) {
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
return TRUE;
}

//-----New coding------//
if(Rectn) {
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS)); //Mouse cursor changes to Cross cursor//
return TRUE;

}//---End of new coding-----//
 

if(zoom) {
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
return TRUE;
}
if(eraser) { //eraser is activated
CWinApp* pApp=AfxGetApp(); //load Square cursor for erasing of image
HICON hIconBang =pApp->LoadCursor(IDC_CURSOR1);
SetCursor(hIconBang);
return TRUE;

}
if(insert) { //insert is activated
CWinApp* pApp=AfxGetApp(); //load Square cursor for erasing of image
HICON hIconBang =pApp->LoadCursor(IDC_CURSOR2);
SetCursor(hIconBang);
return TRUE;

}
 


return CView::OnSetCursor(pWnd, nHitTest, message);
}
 
void CMediVisionView::Segment_Region()
{
int ref, r, c, n;
 
int segment_length = abs(mouse2_x - mouse1_x); // length of the box for segmentation;
int segment_height = abs(mouse2_y - mouse1_y); // height of the box for segmentation
 

region = new int*[segment_height];
for (int i=0; i= ref_intensity-10)) {
n = ((256-(box_y+1))-r)*256 + box_x+c;
image256[n] = 255;
}
}
}
}
if (no_of_rows == 512) {
box_x = mouse1_x - posx512; // 5 is because the StretchDIbits command has
box_y = mouse1_y - posy512; // set the corner of image at (5, 5)
 
n = (512-(box_y+1))*512 + box_x; // +1 because it should not include the current row
ref = 0; // and 512-(...) because in screen bottom left hand corner is (0,0)
 
for (r=0; r= ref_intensity-10)) {
n = ((512-(box_y+1))-r)*512 + box_x+c;
image512[n] = 255;
}
}
}
}
Draw();
return;
 
delete [] region;
}
 
void CMediVisionView::OnFileMultipleopen()
{
// TODO: Add your command handler code here
multiple_open = true;
OpenFile();
}
 
void CMediVisionView::OpenFile()
{
static char BASED_CODE szFilter[] = "DICOM (*.dcm)|*.dcm|Bitmap (*.bmp)| *.bmp|";
 
CFileDialog dlg(TRUE, NULL, NULL, NULL, szFilter);
if (dlg.DoModal() == IDOK) {
m_File1=dlg.GetFileName();
file = m_File1;

}
 
if ((fp = fopen(m_File1, "rb")) == NULL) {
noFile = true;
}
else {

noFile = false;
if (multiple_open) image_no++;
}

Flag3D = false;
ReadFile();

Invalidate(); // Refresh the Window
 
pDC = GetDC();
hdc=pDC->GetSafeHdc();
Draw();
 
}
 
void CMediVisionView::OnRToolbar3DIntensity()
{
// TODO: Add your command handler code here
 
On3dMaximumintensity();
}
 
void CMediVisionView::OnRToolbarMultipleopen()
{
// TODO: Add your command handler code here
OnFileMultipleopen();
}
 

void CMediVisionView::OnRToolbar2Region()
{
// TODO: Add your command handler code here
OnSegmentationRegiongrowing();
}
 
void CMediVisionView::On3dVolumerendering()
{
// TODO: Add your command handler code here
int s, n;
int p=0, q=0;
int iGm, Composite;
float Grad_Mag, Ambient, Mag, Diffuse, Light_Mag, Luminance, Alpha, at, la, lum;
float Intensity;
float Light_x = 128+2.5;
float Light_y = 128+2.5;
float Light_z = 1+3.5;
 
Light_Mag = (float)sqrt(Light_x*Light_x + Light_y*Light_y + Light_z*Light_z);
Ambient = 0.4f;
Diffuse = 0.6f;
 
SetClassificationTable();
 
if (no_of_rows==256) {

//----------------------- Compute the Gradient -------------------------------------------
n = 0;
for (p=0; p 0) {
Grad_x = dcmPixel[s][p*256+(q-1)] - dcmPixel[s][p*256+(q+1)];
Grad_y = dcmPixel[s][(p-1)*256+q] - dcmPixel[s][(p+1)*256+q];
Grad_z = dcmPixel[s-1][n] - dcmPixel[s+1][n];
Grad_Mag = (float)sqrt(Grad_x*Grad_x + Grad_y*Grad_y + Grad_z*Grad_z);
//----------------------- Compute classify -----------------------------------------------
iGm = (Grad_Mag/442.0f) * 64.0f;
Composite = (iGm<<8) | (dcmPixel[s][p*256+q]);
Alpha = (float)alphaTable[Composite]/255.0f;
Luminance = (float)luminanceTable[Composite];;
//----------------------- Compute Shading ------------------------------------------------
Mag =(Grad_x/Grad_Mag * Light_x/Light_Mag) +
(Grad_y/Grad_Mag * Light_y/Light_Mag) +
(Grad_z/Grad_Mag * Light_z/Light_Mag);
 
if (Mag <0.0) Mag = 0.0;
Intensity = Ambient + (Diffuse*Mag);
Luminance = Luminance * Intensity;
//----------------------- Front to back Alpha --------------------------------------------
if (Alpha>0.0) {
at = Alpha * (1.0f - la);
lum = lum + (Luminance * at);
la = la + at;
if (la > 0.97) break;
}
}
}
n++;
image256[n] = lum;
}
}
}
 
else {
// ------------------------------------------------------------------------------------------
n = 0;
for (p=0; p 0) {
Grad_x = dcmPixel[s][p*512+(q-1)] - dcmPixel[s][p*512+(q+1)];
Grad_y = dcmPixel[s][(p-1)*512+q] - dcmPixel[s][(p+1)*512+q];
Grad_z = dcmPixel[s-1][n] - dcmPixel[s+1][n];

Grad_Mag = (float)sqrt(Grad_x*Grad_x + Grad_y*Grad_y + Grad_z*Grad_z);
// -------------------------- Compute classify --------------------------------------------
iGm = (Grad_Mag/442.0f) * 64.0f;
Composite = (iGm<<8) | (dcmPixel[s][p*512+q]);
Alpha = (float)alphaTable[Composite]/255.0f;
Luminance = (float)luminanceTable[Composite];
// -------------------------- Compute Shading ---------------------------------------------
Mag =(Grad_x/Grad_Mag * Light_x/Light_Mag) +
(Grad_y/Grad_Mag * Light_y/Light_Mag) +
(Grad_z/Grad_Mag * Light_z/Light_Mag);
 
if (Mag <0.0) Mag = 0.0;
Intensity = Ambient + (Diffuse*Mag);
Luminance = Luminance * Intensity;
// -------------------------- Front to back Alpha -----------------------------------------
if (Alpha>0.0) {
at = Alpha * (1.0f - la);
lum = lum + (Luminance * at);
la = la + at;
if (la > 0.97) break;
}
}
}
n++;
image512[n] = lum;
}
}
}
pDC = GetDC();
hdc=pDC->GetSafeHdc();
Draw();
}
 
void SetClassificationTable() {
float alpha;
float levWidth, levThreshold;
int index, magnitude, intensity, ind;
 
levThreshold = (float)128.0;
levWidth = (float) 2.0;
 
for (index=0; index<4; index++) {
for (magnitude=0; magnitude < 64; magnitude ++) {
for (intensity=0; intensity < 256; intensity++) {
ind = intensity + (magnitude<<8) + (index<<14);
 
if ((intensity >=levThreshold) && (intensity < (levThreshold + levWidth)))
alpha = ((float)intensity - levThreshold)/levWidth;
else if (intensity < levThreshold)
alpha = (float)0.0;
else
alpha = (float)1.0;
 
if (alpha>0.0) {
alphaTable[ind] = (255.0*alpha);
}
else
alphaTable[ind] = 0;
 
luminanceTable[ind] = 255;
}
}
}
}
 
void CMediVisionView::OnToolsEraser()
{
// TODO: Add your command handler code here
if (!eraser) // Toggle
eraser = true;
else
eraser = false;
}
 
void CMediVisionView::OnToolsBoolean()
{
// TODO: Add your command handler code here
FILE* fb; // Pointer for bitmap file
short c1, c2;
int i, j, c;
int BitmapWidth, BitmapHeight, intval, psize;
short shortval;
 
if ((fb=fopen("d:\\bmestudent\\Medical Visualization 32\\Chee-Boon_LEO-MedicalVisualization31\\512 bitmap\\bitmap512res2(3)-1.bmp", "rb")) == NULL) {
AfxMessageBox("Cannot Open Bitmap File! ");
fclose(fb);
exit(1);
}
 
/*-------------- Read Bitmap File Info ------------------------------------------------
This size is 14 bytes
16 bits : Magic Number "BM"
32 bits : Size of file in 32-bit Integer
16 bits : Reserved 1 (always 0)
16 bits : Reserved 2 (always 0)
32 bits : Starting position of image data, in bytes
---------------------------------------------------------------------------------------*/
 
c1 = fgetc(fb);
c2 = fgetc(fb);
if (c1 != 'B' || c2 != 'M') {
AfxMessageBox("Bitmap File Error 1! ");
return;
}
 
fread(&intval, sizeof(unsigned int), 1, fb);
fread(&shortval, sizeof(unsigned short), 1, fb);
fread(&shortval, sizeof(unsigned short), 1, fb);
fread(&intval, sizeof(unsigned int), 1, fb);
 
/* --------------Read Bitmap Header ----------------------------------------------------
This size is 40 bytes
32 bits : (unsigned) size of this header
32 bits : Width
32 bits : Height
 
16 bits : Planes (no of colour planes, always 1)
16 bits : BitsPerPixel (1 to 24. 1, 4, 8 and 24 are legal.
 
32 bits : (unsigned) compression (1, 8 bit RLE; 2, 4 bit RLE; 3 bitfield)
32 bits : SizeofBitmap in bytes (0 if uncompressed)
32 bits : H-Resolution (Pixels per meter, can be 0)
32 bits : V-Resolution (Pixels per meter, can be 0)
32 bits : (unsigned) ColorsUsed (No. of colours in palette, can be 0)
32 bits : ColorImportant (Minimum number of important colors, can be 0)
----------------------------------------------------------------------------------------*/
 
fread(&intval, sizeof(unsigned int), 1, fb);
fread(&BitmapWidth, sizeof(unsigned int), 1, fb);
fread(&BitmapHeight, sizeof(unsigned int), 1, fb);
 
fread(&shortval, sizeof(unsigned short), 1, fb);
fread(&shortval, sizeof(unsigned short), 1, fb);
 
fread(&intval, sizeof(unsigned int), 1, fb);
fread(&intval, sizeof(unsigned int), 1, fb);
fread(&intval, sizeof(unsigned int), 1, fb);
fread(&intval, sizeof(unsigned int), 1, fb);
fread(&psize, sizeof(unsigned int), 1, fb);
fread(&intval, sizeof(unsigned int), 1, fb);
 
/* ---------------- Read the Color Palette --------------------------------------------*/
 
for (i=0; iGetSafeHdc();
Draw();
 
fclose(fb);
 
delete [] Bitmap_r;
delete [] Bitmap_g;
delete [] Bitmap_b;
 
return;
}
 
void CMediVisionView::BmpDraw()
{
int row, col, data;
int n=0;
 
BITMAPINFOHEADER infoHeader;
infoHeader.biSize = sizeof(BITMAPINFOHEADER);
infoHeader.biWidth = 512;
infoHeader.biHeight = 512;
infoHeader.biPlanes=1;
infoHeader.biBitCount= 24;
infoHeader.biCompression=0;
infoHeader.biSizeImage=0;
infoHeader.biXPelsPerMeter=0;
infoHeader.biYPelsPerMeter=0;
infoHeader.biClrUsed=0;
infoHeader.biClrImportant=0;
 

for(int p=0;p<512;p++) {
for (int q=0;q<512;q++) {
data=Bitmap_r[n];
if(data <= 0) {
argbPixels[p][q] = (unsigned int)(0 | 0 | 0 | 0);

}
else {
argbPixels[p][q] = (unsigned int)(data << 24 | data <<16 | data<<8 | data);
}
n++;
}
}
 
argbPixelsPtr = (unsigned char *) argbPixels;
rgbPixelsPtr = (unsigned char *) rgbPixels;
 
for (row=0; row<512; row++) {
for(col=0; col<512; col++) {
*rgbPixelsPtr++ = *argbPixelsPtr++;
*rgbPixelsPtr++ = *argbPixelsPtr++;
*rgbPixelsPtr++ = *argbPixelsPtr++;
argbPixelsPtr++;
}
}

StretchDIBits(hdc, 10, 10, 512, 512, 0, 0, 512, 512, rgbPixels,(BITMAPINFO*) &infoHeader, 0, SRCCOPY);

return;
}
 

void CMediVisionView::OnToolsMaximation()
{
// TODO: Add your command handler code here
int i, j, n;
n=0;
if (no_of_rows == 256) {
for (j=0; j150) {
image256[n]=255;
store256[n]=255;
}
n++;
}
}
}
else if (no_of_rows == 512) {
for (j=0; j150) {
image512[n]=255;
store512[n]=255;
}
n++;
}
}
}
Draw();
}
 
void CMediVisionView::OnEraser()
{
// TODO: Add your command handler code here
OnToolsEraser();
}
 

 
void CMediVisionView::OnToolsPen()
{
// TODO: Add your command handler code here
if (!insert) // Toggle
insert = true;
else
insert = false;
}
 
void CMediVisionView::OnPen()
{
// TODO: Add your command handler code here
OnToolsPen();
}
 
void CMediVisionView::OnEditPatientData()
{
// CEdit_Patient_Data EditDlg;
// EditDlg.DoModal();
// TODO: Add your command handler code here
EditDlg = new CEdit_Patient_Data(this);
EditDlg -> Create(CEdit_Patient_Data::IDD,this);
EditDlg -> ShowWindow(SW_SHOW);
EditDlg -> Edit_Patient();
// //EditDlg -> OnOK();

 

 

}
 
void CMediVisionView::OnMorpholofical()
{
// TODO: Add your command handler code here
int n;
int rows = 0, cols = 0;
 
if (no_of_rows == 512){
for(rows=0; rows100)||(image512[(n+1)]>100)||(image512[(n-512)]>100)||(image512[((n-512)+1)]>100)){
 
image512[n] =255;
image512[(n+1)] =255;
image512[(n-512)] =255;
image512[(n-512)+1] =255;
 
store512[n] =255;
store512[(n+1)] =255;
store512[(n-512)] =255;
store512[(n-512)+1] =255;
 

}
}
}
pDC = GetDC();
hdc= pDC->GetSafeHdc();
Draw();
 
}
}
 

void CMediVisionView::OnToolsExpansion()
{
cancel1= false;
cancel2= false;
CExpand_Pixel ExpandDlg(this);
ExpandDlg.DoModal();
if(cancel1==false)
{
CRows_Cols RowsColsDlg(this);
RowsColsDlg.DoModal();
if(cancel2== false)
{
 

 
int n,q,i=0;
int rows =0 , cols =0;
int rows512 , cols512 ;
int *temp;
 
temp = new int [512*512];

 
if (Expand_Pixel == 2) {
for(rows=rows1; rowsMoveTo(m_1);
pDc->LineTo(m_1.x, m_2.y);
 
pDc->MoveTo(m_1);
pDc->LineTo(m_2.x, m_1.y);
 
pDc->MoveTo(m_2.x,m_1.y);
pDc->LineTo(m_2.x, m_2.y);
 
pDc->MoveTo(m_1.x,m_2.y);
pDc->LineTo(m_2.x, m_2.y);
 
}
 

 
void CMediVisionView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
 


CPoint ptRefer;
ptRefer = point;
 
point_x = ptRefer.x;
point_y = ptRefer.y;
int n=0;
 
if (minflag == true) {
 
point_x1 = point_x - posx512;
point_y1 = point_y - posy512;
n = (512-(point_y1+1))*512 + point_x1;
// image512[n]=255;
mini= image512[n];
maxflag=true;
MessageBox("Pls Right-Click to find Maximum point WITHIN the box.");
}
 

if(minflag==false && maxflag==true){

point_w1 = point_x - posx512;
point_z1 = point_y - posy512;
n = (512-(point_z1+1))*512 + point_w1;
// image512[n]=255;
maxi= image512[n];
maxflag=false;
}
 
minflag = false;
 
//--------Image Intensity-------//
if(minflag==false && maxflag==false){
int Column,Row;
 
int length, height, refer;
int diff = (maxi - mini);
length= abs(m2_x - m1_x); // length of the rectangular box for segmentation;
height= abs(m2_y - m1_y);

Rectx = m1_x - posx512;
Recty = m1_y - posy512;
 
n = (512-(Recty+1))*512 + Rectx;

refer=0;
for (Row=0; Rowmaxi+(int)(0.2*diff)) || (image512[n]GetSafeHdc();
// Draw();
 
return;
 

}
 
//------------End of coding-----------------//

GeneralMany thankssussAris Adrianto S13 Mar '04 - 18:11 
I use this small-but-very-useful class for a custom image processor in which a user can make a run-time matrix to do convolution and such.
 
And your class helped me much. And the most cool thing is:
 
It's very C++
 
ha!Big Grin | :-D
 
thanx again, you've somewhat helped me in DIP class!
 
Suspicious | :suss: C++ 4 everSuspicious | :suss:
GeneralTemplate-Based Helper ClassesmemberMohammed Hossny9 Mar '04 - 3:31 
hi,
 
i m involved in developping a mathematical template library.
 
i was responsible for the template multi-dimensional array. i faced the problem of rowset and col set and ve a nice idea instead of helper classes.
 
just check this link, http://www.codeproject.com/useritems/Template_Helper_Classes.asp
 

thx for time Smile | :)
 
salam
 
Yours, M. Hossny
General3D Matrixmembermacmac388 Oct '03 - 10:32 
Hi all,
 
i found this article because i looked for a 4x4 matrix class. I ve started up
with a small company this year to offer some 3d laserscan services.
 
What i am looking for is some code to registrate the data from my scanner which comes in a x,y,z points coordinates ascii-file format. To registrate a number of scans i like to transform these x,y,z coordinates with a 4x4 (translation-rotation) matrix.
 
If someone can help me with code, sources etc. please contact me.
 
If someone like to program this for me i can also donate some money for that.
 
Thanks, Mark
GeneralRe: 3D MatrixmemberMohammed Hossny9 Mar '04 - 3:26 
hi man,
 
i found ur post sooo late.
 
i ve worked in this area for two years Smile | :) .
 
i m leading a team in my faculty applying 3d scanning at ur desk (with minimal cost of equipements).
 
i wish we can communicate and exchange experties about 3d scanning.
 

thxs alot for time, salam Smile | :) .
 

 
Yours, M. Hossny

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 6 Jun 2002
Article Copyright 2002 by Alex Chirokov
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid