void PaintImage (ImageDisplay* IDdata)
/* redraw the image on the canvas computing zoom and scroll */
{
  int nXDIB, nYDIB, iZoom, iSrcWid, iSrcHei, iXHalf, iYHalf, K;
  int iXSize, iYSize, iXPos, iYPos, iXPage, iYPage;
  Dimension cWidth, cHeight;
  int i, ch1;
  char TitleString[500], *cptr;

/* blank if there's no image yet */
     if (!IDdata) return; /* this shouldn't happen */
     if (!image[CurImag].valid) {
       if (XtIsRealized (IDdata->canvas)) 
	 XClearArea (XtDisplay (IDdata->canvas), XtWindow (IDdata->canvas), 
		     0, 0, 0, 0, TRUE);
     }
     if (!image[CurImag].pixarray) return;

/* reset window title to file name */
  if (image[CurImag].valid) { /* title for image only */
    cptr = image[CurImag].FileName->sp;
    ch1 = 0;
    for (i=0; i<image[CurImag].FileName->length;i++)
      if (cptr[i]=='/') ch1 = i+1;
    if (image[CurImag].iNumPlanes>1)
      {sprintf (TitleString,"%s, plane %d",
		&cptr[ch1],
		image[CurImag].PlaneNo+1);}
    else /* one plane */
      {sprintf (TitleString,"%s", &cptr[ch1]);}
    XtVaSetValues(IDdata->shell, 
		  XmNtitle,   TitleString,
		  NULL);
  } /* end of label */

  cWidth = IDdata->disp_wid;   /* current display size */
  cHeight = IDdata->disp_hei;

  nXDIB = image[CurImag].iImageNx;
  nYDIB = image[CurImag].iImageNy;
  iZoom = IDdata->zoom;
  if (iZoom == 0) iZoom = 1;
  /* size of display in image pixels */
  iXHalf = IDdata->disp_wid;  /* divide by two later */
  if (iZoom>1) iXHalf =  iXHalf / iZoom;
  if (iZoom<0) iXHalf = -iXHalf * iZoom;
  iYHalf = IDdata->disp_hei; /* divide by two later */
  if (iZoom>1) iYHalf =  iYHalf / iZoom;
  if (iZoom<0) iYHalf = -iYHalf * iZoom;
  iXHalf = min (iXHalf, nXDIB);
  iYHalf = min (iYHalf, nYDIB);
  iSrcWid = iXHalf;
  iSrcHei = iYHalf;
  iXHalf = iXHalf / 2;
  iYHalf = iYHalf / 2;
  /* Size of display area */
  iXSize = IDdata->disp_wid;
  iYSize = IDdata->disp_hei;
  iXSize = min (iXSize, nXDIB);
  iYSize = min (iYSize, nYDIB);
  if (iZoom>1) {iYSize=iYSize*iZoom; iXSize=iXSize*iZoom;}

/*  for negative zooms, iDisp* is set in SetDisplay */
  iXSize = min (iXSize, (int)cWidth);
  iYSize = min (iYSize, (int)cHeight);
  iXSize = max (iXSize, 1);
  iYSize = max (iYSize, 1);
  /* "page" size for scrolling */
  iXPage = iSrcWid;
  iYPage = iSrcHei;
  iXPos = IDdata->scrollx - iXHalf;
  iYPos = IDdata->scrolly - iYHalf;
  iXPos = max (iXPos, 0);
  iYPos = max (iYPos, 0);
  iXPos = min (iXPos, image[CurImag].iImageNx-iXHalf*2);
  iYPos = min (iYPos, image[CurImag].iImageNy-iYHalf*2);
  IDdata->iXCorn = iXPos;
  IDdata->iYCorn = iYPos;

/* copy Pixarray to display */
  ZoomDisplay (IDdata, iXSize, iYSize, iXPos, iYPos, iSrcWid, iSrcHei);

} /* end PaintImage */
示例#2
0
void ClassifyPupilInterior(unsigned char	*raw,		/* image data, RGB order */
							unsigned char	*threshimage,	/* used to mark CR and ARR */
							unsigned char	*dispimage,	/* for displaying what's going on */
							int		ROWS,int COLS,
							double	pupil_circle[4],	/* pupil-iris border */
							int		corneal_point,		/* input: a point inside corneal reflex */
							int		*corneal_reflex_indices, /* output: indices of CR */
							int		*total_cr,			/* output: count of pixels in CR */
							int		*abnormal_red_reflex_indices,	/* output: indices of ARR */
							int		*total_arr,			/* output: count of ARR */
							int		red_reflex_avg[3],	/* output: avg red reflex luminensce */
							int		*red_reflex_class,	/* output: classif. of blob */
							int		*red_reflex_col,	/* output: X-centroid of blob */
							int		*red_reflex_row)	/* output: Y-centroid of blob */

{
int		EYE_ROWS,EYE_COLS,r,c,r2,c2,pass,x,y,center_row,center_col;
int		AvgShade[3],DevShade[3],count,diff,size,touching_count;
int		perim_count,perim_pixel,r3,c3;
double	area;
int		*circle_points,total_circle_points,i,Zoom;
//char	text[100];

if (DisplayGraphics == 1)
  {
  if (pupil_circle[3] >= 1.0)
	Zoom=(int)(pupil_circle[3]*3.0);
  else if (pupil_circle[2] >= 1.0)
	Zoom=(int)(pupil_circle[2]*3.0);
  else
	Zoom=MaxIrisRad*2;
  ZoomDisplay(dispimage,ROWS,COLS,corneal_point/COLS,corneal_point%COLS,Zoom,Zoom,ZoomSteps);
  circle_points=(int *)calloc(MaxIrisRad*8,sizeof(int));
  Sleep(FramePause/4);
  if (pupil_circle[2] >= 0.0)
    {
	MakeCircleIndices(pupil_circle[0],pupil_circle[1],pupil_circle[2],
						ROWS,COLS,circle_points,&total_circle_points);
	for (i=0; i<total_circle_points; i++)
	  dispimage[circle_points[i]*3+1]=255;
    }
  if (pupil_circle[3] >= 0.0)
    {
	MakeCircleIndices(pupil_circle[0],pupil_circle[1],pupil_circle[3],
						ROWS,COLS,circle_points,&total_circle_points);
	for (i=0; i<total_circle_points; i++)
	  dispimage[circle_points[i]*3+1]=dispimage[circle_points[i]*3+0]=255;
    }
  free(circle_points);
  ZoomDisplay(dispimage,ROWS,COLS,corneal_point/COLS,corneal_point%COLS,Zoom,Zoom,0);
  Sleep(FramePause/4);
  }

	/*****************************************************************
	** threshimage keeps track of pixel labels.  First, label the
	** corneal reflex with a distinctive label, so the CR pixels will
	** be ignored in further processing.
	*****************************************************************/

size=RegionFill(threshimage,ROWS,COLS,corneal_point/COLS,corneal_point%COLS,
		POSS_REFLEX,CORN_REFLEX);

	/*****************************************************************
	** if there is no red circle, then fill cr_indices array and exit
	*****************************************************************/

(*total_arr)=(*total_cr)=0;
(*red_reflex_col)=(*red_reflex_row)=0;
red_reflex_avg[0]=red_reflex_avg[1]=red_reflex_avg[2]=0;
if (pupil_circle[2] <= 0.0)
  {
  for (r=corneal_point/COLS-size; r<corneal_point/COLS+size; r++)
    for (c=corneal_point%COLS-size; c<corneal_point%COLS+size; c++)
      if (r >= 0  &&  r < ROWS  &&  c >= 0  &&  c < COLS  &&
				threshimage[r*COLS+c] == CORN_REFLEX)
        {
        corneal_reflex_indices[*total_cr]=r*COLS+c;
        (*total_cr)++;
		if (DisplayGraphics == 1)
		  {
          dispimage[(r*COLS+c)*3+0]/=8;
          dispimage[(r*COLS+c)*3+1]/=8;
          dispimage[(r*COLS+c)*3+2]=255;
		  }
        }
  if (DisplayGraphics == 1)
    {
    ZoomDisplay(dispimage,ROWS,COLS,corneal_point/COLS,corneal_point%COLS,Zoom,Zoom,0);
    Sleep(FramePause/4);
	}
  return;
  }
(*red_reflex_class)=NORMAL;

	/*****************************************************************
	** Four passes through the image data:
	** 	pass 0: find the average intensity inside the pupil
	**	pass 1: find the stddev intensity inside the pupil
	** 	pass 2: label abnormal pixels inside the pupil
	**	pass 3: paint-fill abnormal areas and classify
	*****************************************************************/

EYE_ROWS=EYE_COLS=(int)(pupil_circle[2]*2.0+2.0);	/* inside of pupil */
y=(int)pupil_circle[1]-EYE_ROWS/2;	/* local image bounds to check */
x=(int)pupil_circle[0]-EYE_COLS/2;

AvgShade[0]=AvgShade[1]=AvgShade[2]=count=0;
DevShade[0]=DevShade[1]=DevShade[2]=0;
for (pass=0; pass<4; pass++)
  {
  for (r=y; r<=y+EYE_ROWS; r++)
    for (c=x; c<=x+EYE_COLS; c++)
      {
      if (r < 0  ||  r >= ROWS  ||  c < 0  ||  c >= COLS)
        continue;	/* outside image bounds */
      if (sqrt(SQR((double)r-pupil_circle[1])+SQR((double)c-pupil_circle[0])) > pupil_circle[2])
		{
		threshimage[r*COLS+c]=OTHER;	/* so paint-fill stops at circle */
		continue;	/* outside pupil circle */
		}
      if (threshimage[r*COLS+c] == CORN_REFLEX)
        {
        if (pass == 0)
          {
          corneal_reflex_indices[*total_cr]=r*COLS+c;
          (*total_cr)++;
          }
        continue;	/* don't want to include CR */
        }
      for (r2=-2; r2<=2; r2++)	/* search for 2-deep border of CR */
        {
        for (c2=-2; c2<=2; c2++)
          if (threshimage[(r+r2)*COLS+c+c2] == CORN_REFLEX)
		    break;
        if (c2 <=2) break;
		}
      if (r2 <= 2)
		{
		threshimage[r*COLS+c]=OTHER;
        continue;	/* don't want to include area just around CR */
		}
      if (pass == 0)
        {
		AvgShade[0]+=raw[(r*COLS+c)*3+0];	/* red */
		AvgShade[1]+=raw[(r*COLS+c)*3+1];	/* green */
		AvgShade[2]+=raw[(r*COLS+c)*3+2];	/* blue */
		count++;
        }
      else if (pass == 1)
        {
		DevShade[0]+=SQR(raw[(r*COLS+c)*3+0]-AvgShade[0]);
		DevShade[1]+=SQR(raw[(r*COLS+c)*3+1]-AvgShade[1]);
		DevShade[2]+=SQR(raw[(r*COLS+c)*3+2]-AvgShade[2]);
        }
      else if (pass == 2)
        {
        diff=(raw[(r*COLS+c)*3+0]-AvgShade[0])+
		(raw[(r*COLS+c)*3+1]-AvgShade[1])+
		(raw[(r*COLS+c)*3+2]-AvgShade[2]);
		if (diff > 70  &&  (AvgShade[0] > 200  ||
						raw[(r*COLS+c)*3+0]-AvgShade[0] > 30))
		  threshimage[r*COLS+c]=ABNORMAL;
		else
		  threshimage[r*COLS+c]=OTHER;
        }
      else	/* pass == 3 */
		{
        if (threshimage[r*COLS+c] == ABNORMAL)
          size=RegionFill(threshimage,ROWS,COLS,r,c,ABNORMAL,BRIGHT_CHECKING);
        else
          continue;
        area=(double)size/(M_PI*SQR(pupil_circle[2]));
//sprintf(text,"ARR size %d area %lf (limits %lf %lf)",size,area,MIN_2R_AREA,MAX_2R_AREA);
//MessageBox(NULL,text,"ARR analysis",MB_OK | MB_APPLMODAL);
        if (area < MIN_2R_AREA  ||  area > MAX_2R_AREA)
          {
          size=RegionFill(threshimage,ROWS,COLS,r,c,BRIGHT_CHECKING,OTHER);
          continue;
          }
                /* big enough area -- find centroid and circle-border count */
        center_row=center_col=touching_count=perim_count=0;
        for (r2=r-size; r2<r+size; r2++)
          for (c2=c-size; c2<c+size; c2++)
            if (r2 >= 0  &&  r2 < ROWS  &&  c2 >= 0  &&  c2 < COLS  &&
					threshimage[r2*COLS+c2] == BRIGHT_CHECKING)
              {
              center_row+=r2;
              center_col+=c2;
		      perim_pixel=0;	/* is pixel on perimter of ARR-blob? */
		      for (r3=r2-1; r3<=r2+1; r3++)
				for (c3=c2-1; c3<=c2+1; c3++)
				  {
				  if (r3 >= 0  &&  r3 < ROWS  &&  c3 >= 0  &&  c3 < COLS  &&
						threshimage[r3*COLS+c3] != BRIGHT_CHECKING)
				    perim_pixel=1;
				  }
		      if (perim_pixel == 1)
		        {
		        perim_count++;
                if (fabs(pupil_circle[2]-sqrt(SQR((double)r2-pupil_circle[1])+
						SQR((double)c2-pupil_circle[0])) ) <= 2.5)
		          touching_count++;
                }
		      }
		*red_reflex_col=(int)((double)center_col/(double)size);
		*red_reflex_row=(int)((double)center_row/(double)size);
        if (sqrt(SQR((double)(*red_reflex_row)-pupil_circle[1])+
                 SQR((double)(*red_reflex_col)-pupil_circle[0]))
                < pupil_circle[2])	/* centroid inside pupil */
          {
		  if ((double)touching_count/(double)perim_count > MIN_CRESC)
		    *red_reflex_class=CRESCENT;
          else
		    *red_reflex_class=OTHER_BLOB;
          for (r2=r-size; r2<r+size; r2++)
            for (c2=c-size; c2<c+size; c2++)
              if (r2 >= 0  &&  r2 < ROWS  &&  c2 >= 0  &&  c2 < COLS  &&
                        threshimage[r2*COLS+c2] == BRIGHT_CHECKING)
                {
                abnormal_red_reflex_indices[*total_arr]=r2*COLS+c2;
                (*total_arr)++;
                }
          }
        size=RegionFill(threshimage,ROWS,COLS,r,c,BRIGHT_CHECKING,OTHER);
		}
      }
  if (pass == 0)
    {
    red_reflex_avg[0]=AvgShade[0]=AvgShade[0]/count;
    red_reflex_avg[1]=AvgShade[1]=AvgShade[1]/count;
    red_reflex_avg[2]=AvgShade[2]=AvgShade[2]/count;
//sprintf(text,"RR avg inten %d %d %d",AvgShade[0],AvgShade[1],AvgShade[2]);
//MessageBox(NULL,text,"ARR analysis",MB_OK | MB_APPLMODAL);
    }
  else if (pass == 1)
    {
    DevShade[0]=(int)sqrt((double)DevShade[0]/(double)count);
    DevShade[1]=(int)sqrt((double)DevShade[1]/(double)count);
    DevShade[2]=(int)sqrt((double)DevShade[2]/(double)count);
    }
  if (pass == 0  &&  DisplayGraphics == 1)
    {
    for (i=0; i<(*total_cr); i++)
	  {
      dispimage[corneal_reflex_indices[i]*3+0]/=8;
      dispimage[corneal_reflex_indices[i]*3+1]/=8;
      dispimage[corneal_reflex_indices[i]*3+2]=255;
	  }
    ZoomDisplay(dispimage,ROWS,COLS,corneal_point/COLS,corneal_point%COLS,Zoom,Zoom,0);
    Sleep(FramePause/4);
    }
  }

if (DisplayGraphics == 1)
  {
  for (i=0; i<(*total_arr); i++)
	{
    dispimage[abnormal_red_reflex_indices[i]*3+2]=255;
	if ((*red_reflex_class) == CRESCENT)
	  {
	  dispimage[abnormal_red_reflex_indices[i]*3+1]=255;
	  dispimage[abnormal_red_reflex_indices[i]*3+0]/=8;
	  }
	else
	  {
	  dispimage[abnormal_red_reflex_indices[i]*3+1]/=8;
	  dispimage[abnormal_red_reflex_indices[i]*3+0]=175;
	  }
	}
  ZoomDisplay(dispimage,ROWS,COLS,corneal_point/COLS,corneal_point%COLS,Zoom,Zoom,0);
  Sleep(FramePause);
  }
}