void CWndDisplayTexture::OnLButtonDown(UINT nFlags, CPoint point) { // start drawing line m_bDrawLine = TRUE; // store mouse start coordinates m_pixLineStartU = point.x; m_pixLineStartV = point.y; m_pixLineStopU = point.x; m_pixLineStopV = point.y; // get texture data from surface CTextureData *pTD = (CTextureData*)m_toTexture.GetData(); PIX pixU = point.x-m_pixWinOffsetU; PIX pixV = point.y-m_pixWinOffsetV; if( pixU<0 || pixU>m_pixWinWidth ) return; if( pixV<0 || pixV>m_pixWinHeight) return; pixU = PIX(pixU/m_fWndTexRatio); pixV = PIX(pixV/m_fWndTexRatio); // if there is valid mouse down function set if( m_pLeftMouseButtonClicked != NULL) { // call it m_pLeftMouseButtonClicked(pixU, pixV); } CWnd::OnLButtonDown(nFlags, point); }
void CWndDisplayTexture::OnMouseMove(UINT nFlags, CPoint point) { // if right mouse is down if (nFlags&MK_RBUTTON) { // get texture data from surface CTextureData *pTD = (CTextureData*)m_toTexture.GetData(); PIX pixU = point.x-m_pixWinOffsetU; PIX pixV = point.y-m_pixWinOffsetV; if( pixU<0 || pixU>m_pixWinWidth ) return; if( pixV<0 || pixV>m_pixWinHeight) return; pixU = PIX(pixU/m_fWndTexRatio); pixV = PIX(pixV/m_fWndTexRatio); // if there is valid mouse down function set if( m_pRightMouseButtonMoved != NULL) { // call it m_pRightMouseButtonMoved(pixU, pixV); } // if left mouse is down } else if (nFlags&MK_LBUTTON) { // store mouse coordinates m_pixLineStopU = point.x; m_pixLineStopV = point.y; } CWnd::OnMouseMove(nFlags, point); }
IplImage* findedge(IplImage* img,int thresh) { int i,j,ht,wd; ht=img->height; wd=img->width; IplImage* res; res=cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1); for(i=0;i<ht;i++) for(j=0;j<wd;j++) PIX(res,i,j,0)=(uchar)(.33*PIX(img,i,j,0)+.56*PIX(img,i,j,1)+.11*PIX(img,i,j,2)); for(i=1;i<ht-1;i++) for(j=1;j<wd-1;j++) PIX(res,i,j,0)=(pixelcheck(img,thresh,i,j))?0:255; return res; }
void treasure::set_direct_frame(short whatframe) { unsigned char * data; frame = whatframe; data = screenp->myloader->graphics[PIX(order, family)]; bmp = (data+3 + frame*size); }
static INDEX SliderPixToIndex(PIX pixOffset, INDEX iVisible, INDEX iTotal, PIXaabbox2D boxFull) { FLOAT fSize = ClampUp(FLOAT(iVisible)/iTotal, 1.0f); PIX pixFull = boxFull.Size()(2); PIX pixSize = PIX(pixFull*fSize); if (pixSize>=boxFull.Size()(2)) { return 0; } return (iTotal*pixOffset)/pixFull; }
void CWndDisplayTexture::OnRButtonDown(UINT nFlags, CPoint point) { // get texture data from surface CTextureData *pTD = (CTextureData*)m_toTexture.GetData(); PIX pixU = point.x-m_pixWinOffsetU; PIX pixV = point.y-m_pixWinOffsetV; if( pixU<0 || pixU>m_pixWinWidth ) return; if( pixV<0 || pixV>m_pixWinHeight) return; pixU = PIX(pixU/m_fWndTexRatio); pixV = PIX(pixV/m_fWndTexRatio); // if there is valid mouse down function set if( m_pRightMouseButtonClicked != NULL) { // call it m_pRightMouseButtonClicked(pixU, pixV); } CWnd::OnRButtonDown(nFlags, point); }
/** interpolateBiLin: bi-linear interpolation function, see interpolate */ void _FLT(interpolateBiLin)(unsigned char *rv, float x, float y, unsigned char* img, int width, int height, unsigned char def) { if (x < 0 || x > width - 1 || y < 0 || y > height - 1) { _FLT(interpolateBiLinBorder)(rv, x, y, img, width, height, def); } else { int x_f = myfloor(x); int x_c = x_f+1; int y_f = myfloor(y); int y_c = y_f+1; short v1 = PIX(img, x_c, y_c, width, height); short v2 = PIX(img, x_c, y_f, width, height); short v3 = PIX(img, x_f, y_c, width, height); short v4 = PIX(img, x_f, y_f, width, height); float s = (v1*(x - x_f)+v3*(x_c - x))*(y - y_f) + (v2*(x - x_f) + v4*(x_c - x))*(y_c - y); *rv = (unsigned char)s; } }
static PIXaabbox2D GetSliderBox(INDEX iFirst, INDEX iVisible, INDEX iTotal, PIXaabbox2D boxFull) { FLOAT fSize = ClampUp(FLOAT(iVisible)/iTotal, 1.0f); PIX pixFull = boxFull.Size()(2); PIX pixSize = PIX(pixFull*fSize); pixSize = ClampDn(pixSize, boxFull.Size()(1)); PIX pixTop = pixFull*(FLOAT(iFirst)/iTotal)+boxFull.Min()(2); PIX pixI0 = boxFull.Min()(1); PIX pixI1 = boxFull.Max()(1); return PIXaabbox2D(PIX2D(pixI0, pixTop), PIX2D(pixI1, pixTop+pixSize)); }
void CWndDisplayTexture::OnLButtonUp(UINT nFlags, CPoint point) { // stop drawing line m_bDrawLine = FALSE; // get texture data from surface CTextureData *pTD = (CTextureData*)m_toTexture.GetData(); PIX pixU = point.x-m_pixWinOffsetU; PIX pixV = point.y-m_pixWinOffsetV; if( pixU<0 || pixU>m_pixWinWidth ) return; if( pixV<0 || pixV>m_pixWinHeight) return; pixU = PIX(pixU/m_fWndTexRatio); pixV = PIX(pixV/m_fWndTexRatio); // if there is valid mouse down function set if( m_pLeftMouseButtonReleased != NULL) { // call it m_pLeftMouseButtonReleased(pixU, pixV); } CWnd::OnLButtonUp(nFlags, point); }
int pixelcheck(IplImage* img,int thresh,int x,int y) { int i,j,max,min; min=256; max=-1; for(i=x-1;i<=x+1;i++) { if(i<0 || i>=img->height) continue; for(j=y-1;j<=y+1;j++) { if(j<0 || j>=img->width) continue; if(PIX(img,i,j,0)<min) min=PIX(img,i,j,0); if(PIX(img,i,j,0)>max) max=PIX(img,i,j,0); } } if((max-min)>thresh) return 1; return 0; }
void clearnoise(IplImage *frame, int action, int kernel){ int i, j, black, white, i2, j2, k; int ht = frame->height; int wd = frame->width; for(i = 0; i< ht; i++){ for(j = 0; j< wd; j++){ i2 = i-2; j2 = j-2; for(k=1; k<9; k++){ if(i2<0 || i2>=ht || j2<0 || j2>=wd) continue; if(PIX(frame,i2+(k/3),j2+(k%3),0)==0) black++; else white++; if(!action) if(white>black) PIX(frame,i2+(k/3),j2+(k%3),0)=255; else if(black>white) PIX(frame,i2+(k/3),j2+(k%3),0)=0; } } } }
void CDlgCreateSpecularTexture::DrawGraph( CDrawPort *pdp, FLOAT fExp) { pdp->Fill(C_WHITE|CT_OPAQUE); PIX pixSizeI = pdp->GetWidth(); PIX pixSizeJ = pdp->GetHeight(); PIX pixLastI = 0; PIX pixLastJ = 0; for (PIX pixI=0; pixI<pixSizeI; pixI++) { FLOAT fAlpha = 90.0f*pixI/pixSizeI; FLOAT fCos = FLOAT(pow(Cos(fAlpha), fExp)); PIX pixJ = PIX(pixSizeJ*(1-fCos)); pdp->DrawLine(pixLastI, pixLastJ, pixI, pixJ, C_BLACK|CT_OPAQUE); pixLastI = pixI; pixLastJ = pixJ; } }
IplImage* detectthis(IplImage *img, int b,int g,int r,int b1, int g1, int r1) { int i,j,ht,wd,flag; ht=img->height; wd=img->width; IplImage* grey=cvCreateImage(cvSize(wd,ht),IPL_DEPTH_8U,1); for(i=0;i<ht;i++){ for(j=0;j<wd;j++){ flag=0; if(PIX(img,i,j,0)>b-b1&&PIX(img,i,j,0)<b+b1) if(PIX(img,i,j,1)>g-g1&&PIX(img,i,j,1)<g+g1) if(PIX(img,i,j,2)>r-r1&&PIX(img,i,j,2)<r+r1) flag=1; PIX(grey,i,j,0)=(flag)?255:0; } } return grey; }
/* acsrej_init -- get the initial average pixel values Description: ------------ Get the initial average according to the specified scheme Date Author Description ---- ------ ----------- 22-Sep-1998 W.J. Hack initial version, uses multiamp noise,gain 20-Mar-2000 W.J. Hack corrected problem with rog2, needed to be array 15-Apr-2002 W.J. Hack correctly zero'd out npts array, added DQ checking for BOTH median and minimum images, also added ERR array for median image. 26-Aug-2002 J. Blakeslee Modified threshhold for minimum to use SCALENSE only with sky-subtracted pixels. 01-Dec-2015 P.L. Lim Calculations now entirely in electrons. 13-Jan-2016 P.L. Lim Removed variance init and cleaned up function. */ int acsrej_init (IODescPtr ipsci[], IODescPtr ipdq[], clpar *par, int nimgs, int dim_x, int dim_y, float efac[], float skyval[], SingleGroup *sg, float *work) { /* Parameters: ipsci i: Array of pointers to SCI extension of the given EXTVER, each pointer is an input image. Unit now in electrons. ipdq i: Array of pointers to DQ extension of the given EXTVER, each pointer is an input image. par i: User specified parameters. nimgs i: Number of input images. dim_x, dim_y i: Image dimension taken from the first input image. All images must have the same dimension. efac i: Array of EXPTIME for each image. If all inputs have EXPTIME=0 (all biases), then the values are all set to 1. skyval i: Array of sky values for each input image. Unit now in electrons. sg o: Its "sci" component is the average image used for comparison during CR rejection. Unit is e/s. This is really the median or minimum depending on "initgues" provided by the user. work o: Intermediate result used to calculate sg but not used outside this function. */ extern int status; float val, raw, dumf; int i, j, n, p, dum; float *buf; short *bufdq; int *npts, *ipts; short dqpat; Hdr dqhdr; void ipiksrt (float [], int, int[]); /* -------------------------------- begin ------------------------------- */ dqpat = par->badinpdq; ipts = calloc (nimgs, sizeof(int)); npts = calloc (dim_x, sizeof(int)); buf = calloc (dim_x, sizeof(float)); bufdq = calloc (dim_x, sizeof(short)); /* Use the stack median to construct the initial average. */ if (strncmp(par->initgues, "median", 3) == 0) { for (j = 0; j < dim_y; j++) { memset (npts, 0, dim_x*sizeof(int)); for (n = 0; n < nimgs; n++) { initHdr(&dqhdr); getHeader(ipdq[n], &dqhdr); getFloatLine (ipsci[n], j, buf); /* electrons */ getShortLine (ipdq[n], j, bufdq); freeHdr(&dqhdr); /* Only use GOOD pixels to build initial image. work array is already initialized to zeroes in acsrej_do.c */ if (efac[n] > 0.) { for (i = 0; i < dim_x; i++) { if ((bufdq[i] & dqpat) == OK) { PIX(work, npts[i], i, nimgs) = (buf[i] - skyval[n]) / efac[n]; /* e/s */ npts[i] += 1; } } } } /* End of nimgs loop */ /* ALL AMPS */ for (i = 0; i < dim_x; i++) { dum = npts[i]; /* Number of good data points */ if (dum == 0) Pix(sg->sci.data, i, j) = 0.0F; else { /* Setup index array for sorting... */ for (p=0; p < nimgs; p++) ipts[p] = p; /* Sort pixel stack and corresponding index array. */ ipiksrt (&PIX(work, 0, i, nimgs), dum, ipts); /* Even number of input images for this pixel */ if ((dum / 2) * 2 == dum) { Pix(sg->sci.data, i, j) = (PIX(work, dum / 2 - 1, i, nimgs) + PIX(work, dum / 2, i, nimgs)) / 2.; } else { Pix(sg->sci.data, i, j) = PIX(work, dum / 2, i, nimgs); } } } /* End loop over ALL AMPS used on pixels in the line */ } /* End loop over lines */ /* use the minimum to construct the initial average */ } else { if (strncmp(par->initgues, "minimum", 3) != 0) { sprintf (MsgText, "Invalid INITGUES value %s, reset it to 'minimum'", par->initgues); trlwarn (MsgText); strcpy (par->initgues, "minimum"); } for (n = 0; n < nimgs; n++) { initHdr(&dqhdr); getHeader(ipdq[n], &dqhdr); for (j = 0; j < dim_y; j++) { getFloatLine (ipsci[n], j, buf); /* electrons */ getShortLine (ipdq[n], j, bufdq); /* ALL AMPS */ for (i = 0; i < dim_x; i++) { raw = buf[i]; /* e */ dumf = raw - skyval[n]; /* e */ if (efac[n] > 0.) { /* Can be negative */ val = dumf / efac[n]; /* e/s */ } else { val = 0.; } if ( (n == 0) || (val < Pix(sg->sci.data, i, j)) ) { /* If this pixel is bad in the first image, then the min is automatically set to 0. As a result, only negative val is going to be stored and valid positive min is ignored. SLIGHTLY BUGGY HERE??? */ if ((bufdq[i] & dqpat) == OK && (efac[n] > 0.)) { Pix(sg->sci.data, i, j) = val; /* e/s */ } else { Pix(sg->sci.data, i, j) = 0.; } } } /* End of loop over ALL AMPS for this line in each image */ } /* End of loop over lines in image (y) */ freeHdr(&dqhdr); } /* End of loop over images in set */ } /* free the memory */ free (ipts); free (npts); free (buf); free (bufdq); return (status); }
int rej_init (IODescPtr ipsci[], IODescPtr ipdq[], clpar *par, int nimgs, int dim_x, int dim_y, multiamp noise, multiamp gain, float efac[], float skyval[], DataUnits bunit[], SingleGroup *sg, float *work) { extern int status; float scale, val, raw, raw0, signal0; float *buf; short *bufdq; float *exp2; int i, j, n; int dum; int *npts, *ipts; float noise2[NAMPS], rog2[NAMPS]; float gain2[NAMPS]; float nse[2], gn[2]; int ampx, ampy, detector, chip; int k, p; short dqpat; float exp2n, expn; int non_zero; Hdr dqhdr; void ipiksrt (float [], int, int[]); void get_nsegn (int, int, int, int, float *, float*, float *, float *); /* -------------------------------- begin ------------------------------ */ expn=0.0f; scale = par->scalense / 100.; ampx = gain.colx; ampy = gain.coly; detector = gain.detector; chip = gain.chip; dqpat = par->badinpdq; ipts = calloc (nimgs, sizeof(int)); npts = calloc (dim_x, sizeof(int)); buf = calloc (dim_x, sizeof(float)); exp2 = (float *) calloc (nimgs, sizeof(float)); bufdq = calloc (dim_x, sizeof(short)); for (k = 0; k < NAMPS; k++) { gain2[k] = 0.; noise2[k] = 0.; /* Assumption: ALL images have the same noise/gain values */ rog2[k] = SQ(noise.val[k]); } non_zero = 0; for (n = 0; n < nimgs; n++) { exp2[n] = SQ(efac[n]); if (efac[n] > 0.) non_zero++; } get_nsegn (detector, chip, ampx, ampy, gain.val, rog2, gain2, noise2); /* Use the stack median to construct the initial average */ if (strncmp(par->initgues, "median", 3) == 0) { for (j = 0; j < dim_y; j++) { memset (npts, 0, dim_x*sizeof(int)); /* Set up the gain and noise values used for this line ** in ALL images */ if (j < ampy ) { gn[0] = gain2[AMP_C]; gn[1] = gain2[AMP_D]; nse[0] = noise2[AMP_C]; nse[1] = noise2[AMP_D]; } else { gn[0] = gain2[AMP_A]; gn[1] = gain2[AMP_B]; nse[0] = noise2[AMP_A]; nse[1] = noise2[AMP_B]; } for (n = 0; n < nimgs; n++) { initHdr(&dqhdr); getHeader(ipdq[n],&dqhdr); getFloatLine (ipsci[n], j, buf); getShortLine (ipdq[n], j, bufdq); freeHdr(&dqhdr); /* Rescale SCI data, if necessary */ if (bunit[n] == COUNTRATE) { for (i = 0; i < dim_x; i++) { buf[i] *= efac[n]; } } for (i = 0; i < dim_x; i++) { if (efac[n] > 0.) { /* Only use GOOD pixels to build initial image */ if ((bufdq[i] & dqpat) == OK) { PIX(work,npts[i],i,nimgs) = (buf[i] - skyval[n]) / efac[n]; npts[i] += 1; } } else { PIX(work,npts[i],i,nimgs) = 0.; } } } for (i = 0; i < ampx; i++) { dum = npts[i]; if (dum == 0) Pix(sg->sci.data,i,j) = 0.0F; else { /* Setup index array for sorting... */ for (p=0; p < nimgs; p++) ipts[p] = p; /* Sort pixel stack and corresponding index array. */ ipiksrt (&PIX(work,0,i,nimgs), dum, ipts); /* Use sorted index array to match proper exptimes to selected pixels for use in ERR array calculation. */ if ((dum/2)*2 == dum) { /* Even number of input images for this pixel */ Pix(sg->sci.data,i,j) = (PIX(work,dum/2-1,i,nimgs) + PIX(work,dum/2,i,nimgs)) / 2.; expn = (exp2[ipts[dum/2-1]] + exp2[ipts[dum/2]]) / 2.; } else { /* Odd number of input images for this pixel */ Pix(sg->sci.data,i,j) = PIX(work,dum/2,i,nimgs); expn = exp2[ipts[dum/2]]; } } raw0 = Pix(sg->sci.data,i,j); exp2n = (expn > 0.) ? expn : 1.; Pix(sg->err.data,i,j) = (nse[0]+ raw0/gn[0] + SQ(scale*raw0)) / exp2n; } /* End loop over FIRST AMP used on pixels in the line */ for (i = ampx; i < dim_x; i++) { dum = npts[i]; if (dum == 0) Pix(sg->sci.data,i,j) = 0.0F; else { for (p=0; p < nimgs; p++) ipts[p] = p; ipiksrt (&PIX(work,0,i,nimgs), dum, ipts); if ((dum/2)*2 == dum) { /* Even number of input images for this pixel */ Pix(sg->sci.data,i,j) = (PIX(work,dum/2-1,i,nimgs) + PIX(work,dum/2,i,nimgs)) / 2.; expn = (exp2[ipts[dum/2-1]] + exp2[ipts[dum/2]]) / 2.; } else { Pix(sg->sci.data,i,j) = PIX(work,dum/2,i,nimgs); expn = exp2[ipts[dum/2]]; } } raw0 = Pix(sg->sci.data,i,j); exp2n = (expn > 0.) ? expn : 1.; Pix(sg->err.data,i,j) = (nse[1]+ raw0/gn[1] + SQ(scale*raw0)) / exp2n; } /* End loop over SECOND AMP used on pixels in the line */ } /* End loop over lines */ } else { /* use the minimum to construct the initial average */ if (strncmp(par->initgues, "minimum", 3) != 0) { sprintf (MsgText,"Invalid INITGUES value %s, reset it to 'minimum'", par->initgues); trlwarn (MsgText); strcpy (par->initgues, "minimum"); } for (n = 0; n < nimgs; n++) { initHdr(&dqhdr); getHeader(ipdq[n],&dqhdr); for (j = 0; j < dim_y; j++) { /* Set up the gain and noise values used for this line ** in ALL images */ if (j < ampy ) { gn[0] = gain2[AMP_C]; gn[1] = gain2[AMP_D]; nse[0] = noise2[AMP_C]; nse[1] = noise2[AMP_D]; } else { gn[0] = gain2[AMP_A]; gn[1] = gain2[AMP_B]; nse[0] = noise2[AMP_A]; nse[1] = noise2[AMP_B]; } getFloatLine (ipsci[n], j, buf); getShortLine (ipdq[n], j, bufdq); /* Rescale SCI data, if necessary */ if (bunit[n] == COUNTRATE) { for (i = 0; i < dim_x; i++) { buf[i] *= efac[n]; } } /* AMPS C and D */ for (i = 0; i < ampx; i++) { raw = buf[i]; raw0 = (raw > 0.)? raw : 0.; signal0 = ((raw - skyval[n]) > 0.) ? (raw - skyval[n]) : 0.; if (efac[n] > 0.) { val = (raw - skyval[n]) / efac[n]; } else { val = 0.; } if ((n == 0) || (val < Pix(sg->sci.data,i,j)) ) { if ((bufdq[i] & dqpat) == OK && (efac[n] > 0.)) { Pix(sg->sci.data,i,j) = val; /*Pix(sg->err.data,i,j) = (nse[0]+ raw0/gn[0] + SQ(scale*raw0)) / exp2[n];*/ Pix(sg->err.data,i,j) = (nse[0] + raw0/gn[0] + SQ(scale*signal0)) / exp2[n]; } else { Pix(sg->sci.data,i,j) = 0.; Pix(sg->err.data,i,j) = 0.; } } } /* End of loop over FIRST AMP for this line in each image */ for (i = ampx; i < dim_x; i++) { raw = buf[i]; raw0 = (raw > 0.)? raw : 0.; signal0 = ((raw - skyval[n]) > 0.) ? (raw - skyval[n]) : 0.; if (efac[n] > 0.) { val = (raw - skyval[n]) / efac[n]; } else { val = 0.; } if ((n == 0) || (val<Pix(sg->sci.data,i,j) && ((bufdq[i]&dqpat)==OK))) { Pix(sg->sci.data,i,j) = val; if (efac[n] > 0.) { Pix(sg->err.data,i,j) = (nse[1]+ raw0/gn[1] + SQ(scale*signal0)) / exp2[n]; } else { Pix(sg->err.data,i,j) = 0.; } } } /* End of loop over SECOND AMP for this line in each image */ } /* End of loop over lines in image (y) */ freeHdr(&dqhdr); } /* End of loop over images in set */ } /* free the memory */ free (ipts); free (npts); free (buf); free (exp2); free (bufdq); return (status); }
// print text of current message void PrintMessageText(CDrawPort *pdp) { if (_acmMessages.Count()==0 || _iActiveMessage>=_acmMessages.Count()|| fComputerFadeValue<0.99f) { return; } SetFont2(pdp); // print subject CTString strSubject0; CTString strSubject1; CTString strSubject2; //strSubject.PrintF("%g", _fMsgAppearFade); const char *strSubject = _acmMessages[_iActiveMessage].cm_strSubject; INDEX ctSubjectLen = strlen(strSubject); INDEX ctToPrint = int(_fMsgAppearDelta*20.0f); for (INDEX iChar=0; iChar<ctSubjectLen; iChar++) { char strChar[2]; strChar[0] = strSubject[iChar]; strChar[1] = 0; if (iChar>ctToPrint) { NOTHING; } else if (iChar==ctToPrint) { strSubject2+=strChar; } else if (iChar==ctToPrint-1) { strSubject1+=strChar; } else { strSubject0+=strChar; } } PIX pixWidth0 = pdp->GetTextWidth(strSubject0); PIX pixWidth1 = pdp->GetTextWidth(strSubject1); pdp->PutText(strSubject0, _pixMarginI, _pixMarginJ-1, _colMedium); pdp->PutText(strSubject1, _pixMarginI+pixWidth0, _pixMarginJ-1, LerpColor( _colLight, _colMedium, 0.5f)); pdp->PutText(strSubject2, _pixMarginI+pixWidth0+pixWidth1, _pixMarginJ-1, _colLight); pdp->DrawLine(0, PIX(_pixMarginJ*4), _boxMsgText.Size()(1), PIX(_pixMarginJ*4), _colBoxes); // fill in fresh player statistics if (strncmp(_acmMessages[_iActiveMessage].cm_strText, "$STAT", 5)==0) { _ppenPlayer->GetStats(_strStatsDetails, CST_DETAIL, _ctTextCharsPerRow); _acmMessages[_iActiveMessage].cm_ctFormattedWidth = 0; } // format text _acmMessages[_iActiveMessage].PrepareMessage(_ctTextCharsPerRow); SetFont1(pdp); INDEX ctLineToPrint = int(_fMsgAppearDelta*20.0f); // print it PIX pixJ = _pixMarginJ*4; for (INDEX iLine = _iTextLineOnScreen; iLine<_iTextLineOnScreen+_ctTextLinesOnScreen; iLine++) { INDEX iPrintLine = iLine-_iTextLineOnScreen; if (iPrintLine>ctLineToPrint) { continue; } COLOR col = LerpColor( _colLight, _colMedium, Clamp( FLOAT(ctLineToPrint-iPrintLine)/3, 0.0f, 1.0f)); pdp->PutText(_acmMessages[_iActiveMessage].GetLine(iLine), _pixMarginI, pixJ, col); pixJ+=_pixCharSizeJ; } PIXaabbox2D boxSliderSpace = GetTextSliderSpace(); LCDDrawBox(0,0,boxSliderSpace, _colBoxes); PIXaabbox2D boxSlider = GetTextSliderBox(); COLOR col = _colBoxes; PIXaabbox2D boxSliderTrans = boxSlider; boxSliderTrans+=_boxMsgText.Min(); if (boxSliderTrans>=_vpixMouse) { col = LCDBlinkingColor(_colLight, _colDark); } pdp->Fill( boxSlider.Min()(1)+2, boxSlider.Min()(2)+2, boxSlider.Size()(1)-4, boxSlider.Size()(2)-4, col); }
int main( int argc, char** argv ) { int cmd; float desired[8][8] = { {1,0,0,0,0,0,0,0}, // 0 {0,1,0,0,0,0,0,0}, // 1 {0,0,1,0,0,0,0,0}, // 2 {0,0,0,1,1,0,0,0}, // 3 forward {0,0,0,1,1,0,0,0}, // 4 forward {0,0,0,0,0,1,0,0}, // 5 {0,0,0,0,0,0,1,0}, // 6 {0,0,0,0,0,0,0,1}}; // 7 CvPoint p,q; CvScalar line_color = CV_RGB(0,0,255); CvScalar out_color; const char* name_orig = "Original: press q to save images"; const char* name_ave = "input"; const char* name_weights = "weights"; const char* inputCmdFile_name = "./inputs/dataset1/commandlist.dat"; const char* outputFile_name = "./outputs/output_"; FILE* outputFile; FILE* inputCmdFile; char inputName[64]; char outputName[64]; CvCapture* capture = cvCreateCameraCapture(0) ; CvSize frame_size; CvScalar ave = cvScalar(1); CvRect slice_rect; CvSize slice_size; static IplImage* frame = NULL; static IplImage* frame_g = NULL; static IplImage* frame_small = NULL; static IplImage* frame_weights = NULL; static IplImage* frame_w_big = NULL; static IplImage* frame_w_final = NULL; static IplImage* frame_final = NULL; static IplImage* ave_image = NULL; // static IplImage *scale = NULL; static IplImage* frame_slices[N_SLICES]; float inputs[(SIZE/N_SLICES)*SIZE]; float outputs[N_SLICES]; int choices[N_SLICES]; // float desired[N_SLICES]; // float desired[] = {0,0,0,1,1,0,0,0}; //XXX dummy test... //Evo (int nNets, int nInputs, int nHidden, int nOuts) Evo* evoSlice; int ep; int trial; int stepCnt; int flag = 0; char c; int i,j,k,s; float tmp; //////////////////////////////////////////////////////////////////////////////// // init stuff inputCmdFile = fopen(inputCmdFile_name,"r"); if (inputCmdFile == NULL) {printf("Unable to open: %s",inputCmdFile_name); return 0; } // create windows for looking at stuff // cvNamedWindow( name_slice, CV_WINDOW_AUTOSIZE ); cvNamedWindow( name_weights, CV_WINDOW_AUTOSIZE ); cvNamedWindow( name_ave, CV_WINDOW_AUTOSIZE ); cvNamedWindow( name_orig, CV_WINDOW_AUTOSIZE ); // frame_size = cvSize(frame->width,frame->height); frame_size = cvSize(SIZE,SIZE); #ifdef USECAM // capture a frame so we can get an idea of the size of the source frame = cvQueryFrame( capture ); if( !frame ) return 0; #else sprintf(inputName,"./inputs/dataset1/image0000000000.jpg"); frame = cvLoadImage(inputName, 0 ); if( !frame ){ printf("ERROR OPENING: %s!!!\n",inputName); return 0;} #endif allocateOnDemand( &frame_g, cvSize(frame->width,frame->height), IPL_DEPTH_8U, 1 ); allocateOnDemand( &frame_w_big, cvSize(frame->width,frame->height), IPL_DEPTH_8U, 1 ); allocateOnDemand( &frame_w_final, cvSize(frame->width,frame->height), IPL_DEPTH_8U, 3 ); allocateOnDemand( &frame_final, cvSize(frame->width,frame->height+20), IPL_DEPTH_8U, 3 ); allocateOnDemand( &ave_image, frame_size, IPL_DEPTH_8U, 1 ); allocateOnDemand( &frame_small, frame_size, IPL_DEPTH_8U, 1 ); allocateOnDemand( &frame_weights, frame_size, IPL_DEPTH_8U, 1 ); slice_size = cvSize(ave_image->width/N_SLICES, ave_image->height); for (i=0;i<N_SLICES;i++) { allocateOnDemand( &frame_slices[i], slice_size, IPL_DEPTH_8U, 1); } for(trial=0;trial<N_TRIALS;trial++) { sprintf(outputName,"%s%d.txt", outputFile_name, trial); outputFile = fopen(outputName,"w"); // init each leariner evoSlice = (Evo*)malloc(sizeof(Evo)*N_SLICES); for(i=0;i<N_SLICES;i++) { evoSlice[i] = Evo(N_NETS, (SIZE/N_SLICES)*SIZE, N_HIDDEN, 1); evoSlice[i].choose(); choices[i] = evoSlice[i].choose(); } ep = 0; stepCnt = 0; flag = 0; while(1) { //////////////////////////////////////////////////////////////////////////////// // Pre processing #if 0 // make blank image... cvSet(ave_image, cvScalar(0)); for (i=0;i<NF;i++) { // get image #ifdef USECAM frame = cvQueryFrame( capture ); if( !frame ) break; #else sprintf(inputName,"./inputs/dataset1/image%010d.jpg",stepCnt); frame = cvLoadImage(inputName, 0 ); if( !frame ){ printf("ERROR OPENING: %s!!!\n",inputName); return 0;} stepCnt++; #endif // convert it to grey cvConvertImage(frame, frame_g );//, CV_CVTIMG_FLIP); // resize cvResize(frame_g, frame_small); // take difference cvSub(frame_small, ave_image, ave_image); } for(j=0;j<SIZE;j++) { for(k=0;k<SIZE;k++) { PIX(ave_image,k,j) = (char)(PIX(ave_image,k,j)*10); } } #endif #if 0 frame = cvQueryFrame( capture ); if( !frame ) break; cvConvertImage(frame, frame_g ); cvResize(frame_g, frame_small); cvConvertImage(frame_small, ave_image ); #endif #if 1 sprintf(inputName,"./inputs/dataset1/image%010d.jpg",stepCnt); frame = cvLoadImage(inputName, 0 ); if( !frame ){ printf("ERROR OPENING: %s!!!\n",inputName); break;} cvConvertImage(frame, frame_g ); cvResize(frame_g, frame_small); cvConvertImage(frame_small, ave_image ); // cvCanny(ave_image, ave_image, 50, 40,5); #endif // cvDilate(ave_image, ave_image,NULL,4); //////////////////////////////////////////////////////////////////////////////// // Generate NN inputs // slice it up for (i=0;i<N_SLICES;i++) { slice_rect = cvRect(i*ave_image->width/N_SLICES, 0, ave_image->width/N_SLICES, ave_image->height); cvSetImageROI(ave_image, slice_rect); cvCopy(ave_image, frame_slices[i], NULL); } cvResetImageROI(ave_image); // remove this when we don't care about looking at the ave //////////////////////////////////////////////////////////////////////////////// // Evaluate NN if (stepCnt == N_LEARN) flag = 1; if( (flag == 1) && (stepCnt%N_LEARN == 0)) { // every N_LEARN images switch ep++; fprintf(outputFile,"%d",ep); for(i=0;i<N_SLICES;i++) { evoSlice[i].replace(); choices[i] = evoSlice[i].choose(); fprintf(outputFile,"\t%1.3f",evoSlice[i].netPool[evoSlice[i].best()].grade); } fprintf(outputFile,"\n"); if(ep >= N_EPISODES) break; // draw weights image for(s=0;s<N_SLICES;s++) { for(j=0;j<SIZE;j++) { for(k=0;k<(SIZE/N_SLICES);k++) { tmp = 0; for(i=0;i<N_HIDDEN;i++) { tmp += evoSlice[s].mutant->nodeHidden->w[(j*(SIZE/N_SLICES))+k+1]; } PIX(frame_weights,k+(s*SIZE/N_SLICES),j) = (char)((tmp/N_HIDDEN)*255 + 127); // printf("%d\t",(char)((tmp/N_HIDDEN)*255)); } } } cvResize(frame_weights, frame_w_big, CV_INTER_LINEAR); cvConvertImage(frame_w_big, frame_w_final); } fscanf(inputCmdFile,"%d",&cmd); printf("\nTrial: %d Episode: %d Devin's cmd: %d\n",trial,ep,cmd); for(i=0;i<N_SLICES;i++) printf("%1.3f\t",desired[cmd][i]); printf("\n"); for(i=0;i<N_SLICES;i++) { // cvShowImage( name_slice, frame_slices[i] ); // strip pixel data into a single array for(j=0;j<SIZE;j++) { for(k=0;k<(SIZE/N_SLICES);k++) { inputs[(j*(SIZE/N_SLICES))+k] = (float)PIX(frame_slices[i],k,j)/255.0; } } // printf("\n%d: Eval slice %d\n",stepCnt,i); outputs[i] = evoSlice[i].eval(inputs, &desired[cmd][i]); // outputs[i] = desired[i]; printf("%1.3f\t",outputs[i]); } printf("\n"); for(i=0;i<N_SLICES;i++) { printf("%d\t",choices[i]); } printf("\n"); for(i=0;i<N_SLICES;i++) { printf("%1.3f\t",evoSlice[i].mutant->grade); } printf("\n"); //////////////////////////////////////////////////////////////////////////////// // GUI stuff // copy input image into larger final image cvSetImageROI(frame_final, cvRect(0, 0, frame_w_big->width, frame_w_big->height)); cvConvertImage(frame, frame_final); cvResetImageROI(frame_final); // draw slice markers for(i=1;i<N_SLICES;i++) { // on the final frame... p.x = (int)(i*frame_final->width/N_SLICES); p.y = 0; q.x = p.x; q.y = (int)frame_final->height; cvLine( frame_final, p, q, line_color, 2, CV_AA, 0 ); // on the weights p.x = (int)(i*frame_w_final->width/N_SLICES); p.y = 0; q.x = p.x; q.y = (int)frame_w_final->height; cvLine( frame_w_final, p, q, line_color, 2, CV_AA, 0 ); } // draw output indicators for(i=0;i<N_SLICES;i++) { out_color = CV_RGB(outputs[i]*255,0,0); p.x = (int)(i*frame_final->width/N_SLICES); p.y = (int)(frame_final->height-20); q.x = (int)(p.x+frame_final->width/N_SLICES); q.y = (int)(p.y+20); cvRectangle( frame_final, p, q, out_color, CV_FILLED, CV_AA, 0 ); } cvShowImage( name_ave, ave_image ); cvShowImage( name_orig, frame_final ); cvShowImage( name_weights, frame_w_final ); c = cvWaitKey(2); if( c == 27 ) break; else if( c == 'q') { cvSaveImage("weights.jpg",frame_w_final); cvSaveImage("output.jpg",frame_final); } stepCnt++; if (stepCnt>=(N_STEPS-(N_STEPS%N_LEARN))) { stepCnt=0; rewind(inputCmdFile); } } // end while free(evoSlice); fclose(outputFile); } // end trial for //////////////////////////////////////////////////////////////////////////////// // clean up // delete &evo; fclose(inputCmdFile); cvReleaseCapture( &capture ); cvDestroyWindow( name_ave ); cvDestroyWindow( name_orig ); cvDestroyWindow( name_weights ); }
/* Finish current check-image. */ void reendcheck(picstruct *field, checkstruct *check) { char *buf; size_t padsize; padsize = 0; /* To avoid gcc -Wall warnings */ switch(check->type) { case CHECK_MINIBACKGROUND: case CHECK_MINIBACKRMS: return; case CHECK_IDENTICAL: case CHECK_BACKGROUND: case CHECK_BACKRMS: case CHECK_FILTERED: case CHECK_SUBTRACTED: free(check->pix); free(check->line); check->line = NULL; padsize = (FBSIZE -((check->npix*sizeof(PIXTYPE))%FBSIZE)) % FBSIZE; break; case CHECK_OBJECTS: case CHECK_APERTURES: case CHECK_SUBPSFPROTOS: case CHECK_PSFPROTOS: case CHECK_SUBPCPROTOS: case CHECK_PCPROTOS: case CHECK_PCOPROTOS: case CHECK_SUBPROFILES: case CHECK_PROFILES: case CHECK_ASSOC: case CHECK_PATTERNS: if (bswapflag) swapbytes(check->pix, sizeof(PIXTYPE), (int)check->npix); QFWRITE(check->pix,check->npix*sizeof(PIXTYPE), check->file,check->filename); free(check->pix); padsize = (FBSIZE-((check->npix*sizeof(PIXTYPE))%FBSIZE)) % FBSIZE; break; case CHECK_SEGMENTATION: if (bswapflag) swapbytes(check->pix, sizeof(ULONG), (int)check->npix); QFWRITE(check->pix,check->npix*sizeof(ULONG), check->file,check->filename); free(check->pix); padsize = (FBSIZE -((check->npix*sizeof(ULONG))%FBSIZE)) % FBSIZE; break; case CHECK_SUBOBJECTS: { int y; for (y=field->ymin; y<field->ymax; y++) writecheck(check, &PIX(field, 0, y), field->width); free(check->pix); free(check->line); check->line = NULL; padsize = (FBSIZE -((check->npix*sizeof(PIXTYPE))%FBSIZE)) % FBSIZE; break; } case CHECK_MAPSOM: if (bswapflag) swapbytes(check->pix, sizeof(PIXTYPE), (int)check->npix); QFWRITE(check->pix,check->npix*sizeof(PIXTYPE), check->file,check->filename); free(check->pix); padsize = (FBSIZE -((check->npix*sizeof(USHORT))%FBSIZE)) % FBSIZE; break; default: error(EXIT_FAILURE, "*Internal Error* in ", "endcheck()!"); } QCALLOC(buf, char, FBSIZE); if (padsize) QFWRITE (buf, padsize, check->file, check->filename); free(buf); return; }
// init select-on-render functionality void InitSelectOnRender(PIX pixSizeI, PIX pixSizeJ) { _pixSizeI = pixSizeI; _pixSizeJ = pixSizeJ; // if entity selecting not required if (_pselenSelectOnRender==NULL) { // if vertex selecting not requred if (_pselbvxtSelectOnRender==NULL) { // do nothing return; } // if not lasso and not alternative else if (_pavpixSelectLasso==NULL && !_bSelectAlternative) { // deselect all vertices _pselbvxtSelectOnRender->Clear(); } } // if lasso selection is not on, or is invalid if (_pavpixSelectLasso==NULL || _pavpixSelectLasso->Count()<3 || pixSizeI<2 || pixSizeJ<2) { // do nothing return; } SLONG slMaxOffset = pixSizeI*pixSizeJ-1; // allocate lasso buffer _pubLassoBuffer = (UBYTE*)AllocMemory(_pixSizeI*_pixSizeJ); // clear it memset(_pubLassoBuffer, 0, _pixSizeI*_pixSizeJ); // for each line in lasso INDEX ctpt = _pavpixSelectLasso->Count(); for (INDEX ipt=0; ipt<ctpt; ipt++) { // get its points INDEX ipt0 = ipt; INDEX ipt1 = (ipt+1)%ctpt; // get their coordinates PIX pixI0 = (*_pavpixSelectLasso)[ipt0](1); PIX pixJ0 = (*_pavpixSelectLasso)[ipt0](2); PIX pixI1 = (*_pavpixSelectLasso)[ipt1](1); PIX pixJ1 = (*_pavpixSelectLasso)[ipt1](2); // if any of the coordinates is outside of window if (pixI0<0 || pixI0>=_pixSizeI || pixI1<0 || pixI1>=_pixSizeI || pixJ0<0 || pixJ0>=_pixSizeJ || pixJ1<0 || pixJ1>=_pixSizeJ) { // skip this line continue; } // if line is horizontal if (pixJ0==pixJ1) { // skip it continue; // if line goes upwards } else if (pixJ0>pixJ1) { // make it go downwards Swap(pixI0, pixI1); Swap(pixJ0, pixJ1); } // calculate step FIX16_16 xStep = FIX16_16(FLOAT(pixI1-pixI0)/(pixJ1-pixJ0)); // start in first row FIX16_16 xI = FIX16_16(pixI0); // for each row for(PIX pixJ = pixJ0; pixJ<pixJ1; pixJ++) { // get offset SLONG slOffset = pixJ*_pixSizeI+PIX(xI); // if offset is valid if (slOffset>=0 && slOffset<=slMaxOffset) { // invert the pixel in that row _pubLassoBuffer[slOffset] ^= 0xFF; } // step the line xI+=xStep; } } // for each row in lasso buffer for(PIX pixJ = 0; pixJ<_pixSizeJ; pixJ++) { // for each pixel in the row, except the last one UBYTE *pub = _pubLassoBuffer+pixJ*_pixSizeI; for(PIX pixI = 0; pixI<_pixSizeI-1; pixI++) { // xor it to the next one pub[1]^=pub[0]; pub++; } } }
//# MENU lcd void lcd_menu() { getInputWaitRelease(); lcdClear(); lcdPrintln("LCD:"); lcdDisplay(); ON(LED1); uint16_t x,y; uint8_t rgb=0; uint8_t ct=0x3a; uint16_t rgba[]= { RGB(0xff,0,0), RGB(0,0xff,0), RGB(0,0,0xff), RGB(0,0xff,0xff),RGB(0xff,0,0xff),RGB(0xff,0xff,0), RGB(0xff,0xff,0xff),0 }; while(1) { switch(getInputWaitRepeat()) { case BTN_DOWN: lcd_select(); lcdWrite(TYPE_CMD,0x3a); lcdWrite(TYPE_DATA,5); lcdWrite(TYPE_CMD,0x2C); for (y=0; y<128; y++) { for (x=0; x<RESX; x++) { if (x<20) { if(y<64) { PIX(0xff,(0xff-(0xff&(y<<2))),(0xff-(0xff&(y<<2)))); } else { PIX((0xff-(0xff&(y<<2))),0,0); }; } else if (x <40) { if(y<64) { PIX((0xff-(0xff&(y<<2))),0xff,(0xff-(0xff&(y<<2)))); } else { PIX(0,(0xff-(0xff&(y<<2))),0); }; } else if (x <60) { if(y<64) { PIX((0xff-(0xff&(y<<2))),(0xff-(0xff&(y<<2))),0xff); } else { PIX(0,0,(0xff-(0xff&(y<<2)))); }; } else if (x <80) { if(y<64) { PIX(((0xff&(y<<2))),0,0); } else { PIX(0xff,((0xff&(y<<2))),((0xff&(y<<2)))); }; } else if (x <100) { if(y<64) { PIX(0,((0xff&(y<<2))),0); } else { PIX(((0xff&(y<<2))),0xff,((0xff&(y<<2)))); }; } else if (x <120) { if(y<64) { PIX(0,0,((0xff&(y<<2)))); } else { PIX(((0xff&(y<<2))),((0xff&(y<<2))),0xff); }; } else { PIX(0,0,0); } }; }; for (y=128; y<RESY; y++) { for (x=0; x<RESX; x++) { PIX(0,0,0); }; }; lcd_deselect(); break; case BTN_LEFT: ct--; lcd_select(); lcdWrite(TYPE_CMD,0x25); lcdWrite(TYPE_DATA, ct); lcd_deselect(); break; case BTN_RIGHT: ct++; lcd_select(); lcdWrite(TYPE_CMD,0x25); lcdWrite(TYPE_DATA, ct); lcd_deselect(); break; case BTN_UP: lcd_select(); lcdWrite(TYPE_CMD,0x3a); lcdWrite(TYPE_DATA,5); lcdWrite(TYPE_CMD,0x2C); if(rgb==0) { for (y=0; y<RESY; y++) { for (x=0; x<RESX; x++) { if(x==0 || x==RESX-1 || y==0 || y==RESY-1) { PIX(0xff,0,0); } else if(x==1 || x==RESX-2 || y==1 || y==RESY-2) { PIX(0xff,0xff,0); } else if(x==2 || x==RESX-3 || y==2 || y==RESY-3) { PIX(0,0,0xff); } else { PIX(0xff,0xff,0xff); }; }; }; } else { for (y=0; y<RESY; y++) { for (x=0; x<RESX; x++) { lcdWrite(TYPE_DATA,rgba[rgb-1]>>8); lcdWrite(TYPE_DATA,rgba[rgb-1]&0xff); }; }; }; lcd_deselect(); rgb=(rgb+1)%(1+(sizeof(rgba)/sizeof(*rgba))); break; case BTN_ENTER: lcd_select(); lcdWrite(TYPE_CMD,0x3a); lcdWrite(TYPE_DATA,2); lcd_deselect(); return; }; getInputWaitRelease(); }; };
void blur(ofPixels &pix) { #define PIX(x, y) pix.getColor(ofClamp(x,0,1023), ofClamp(y,0,767)) #define RAD 0.2 // blur X for (int x = 0; x < 1024; ++x) for (int y = 0; y < 768; ++y) { ofColor col(0); col += PIX(x - 4*RAD, y) * 0.000215825; col += PIX(x - 3*RAD, y) * 0.00579007; col += PIX(x - 2*RAD, y) * 0.059897; col += PIX(x - 1*RAD, y) * 0.241811; col += PIX(x , y) * 0.384572; col += PIX(x + 1*RAD, y) * 0.241811; col += PIX(x + 2*RAD, y) * 0.059897; col += PIX(x + 3*RAD, y) * 0.00579007; col += PIX(x + 4*RAD, y) * 0.000215825; pix.setColor(x, y, col); } // blur Y for (int x = 0; x < 1024; ++x) for (int y = 0; y < 768; ++y) { ofColor col(0); col += PIX(x, y - 4*RAD) * 0.000215825; col += PIX(x, y - 3*RAD) * 0.00579007; col += PIX(x, y - 2*RAD) * 0.059897; col += PIX(x, y - 1*RAD) * 0.241811; col += PIX(x, y ) * 0.384572; col += PIX(x, y + 1*RAD) * 0.241811; col += PIX(x, y + 2*RAD) * 0.059897; col += PIX(x, y + 3*RAD) * 0.00579007; col += PIX(x, y + 4*RAD) * 0.000215825; pix.setColor(x, y, col); } }
// Triscan scaling to 2x // derivative of scale2x -- scale2x.sf.net // The name expands to either // Scale_TriScanFilter (for plain C) or // Scale_MMX_TriScanFilter (for MMX) // [others when platforms are added] void SCALE_(TriScanFilter) (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r) { int x, y; const int w = src->w, h = src->h; int xend, yend; int dsrc, ddst; SDL_Rect *region = r; SDL_Rect limits; SDL_PixelFormat *fmt = dst->format; const int sp = src->pitch, dp = dst->pitch; const int bpp = fmt->BytesPerPixel; const int slen = sp / bpp, dlen = dp / bpp; // for clarity purposes, the 'pixels' array here is transposed Uint32 pixels[3][3]; Uint32 *src_p = (Uint32 *)src->pixels; Uint32 *dst_p = (Uint32 *)dst->pixels; int prevline, nextline; // these macros are for clarity; they make the current pixel (0,0) // and allow to access pixels in all directions #define PIX(x, y) (pixels[1 + (x)][1 + (y)]) #define TRISCAN_YUV_MED 100 // medium tolerance pixel comparison #define TRISCAN_CMPYUV(p1, p2) \ (PIX p1 == PIX p2 || SCALE_CMPYUV (PIX p1, PIX p2, TRISCAN_YUV_MED)) SCALE_(PlatInit) (); // expand updated region if necessary // pixels neighbooring the updated region may // change as a result of updates limits.x = 0; limits.y = 0; limits.w = src->w; limits.h = src->h; Scale_ExpandRect (region, 1, &limits); xend = region->x + region->w; yend = region->y + region->h; dsrc = slen - region->w; ddst = (dlen - region->w) * 2; // move ptrs to the first updated pixel src_p += slen * region->y + region->x; dst_p += (dlen * region->y + region->x) * 2; for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) { if (y > 0) prevline = -slen; else prevline = 0; if (y < h - 1) nextline = slen; else nextline = 0; // prime the (tiny) sliding-window pixel arrays PIX( 1, 0) = src_p[0]; if (region->x > 0) PIX( 0, 0) = src_p[-1]; else PIX( 0, 0) = PIX( 1, 0); for (x = region->x; x < xend; ++x, ++src_p, dst_p += 2) { // slide the window PIX(-1, 0) = PIX( 0, 0); PIX( 0, -1) = src_p[prevline]; PIX( 0, 0) = PIX( 1, 0); PIX( 0, 1) = src_p[nextline]; if (x < w - 1) PIX( 1, 0) = src_p[1]; else PIX( 1, 0) = PIX( 0, 0); if (!TRISCAN_CMPYUV (( 0, -1), ( 0, 1)) && !TRISCAN_CMPYUV ((-1, 0), ( 1, 0))) { if (TRISCAN_CMPYUV ((-1, 0), ( 0, -1))) dst_p[0] = Scale_Blend_11 (PIX(-1, 0), PIX(0, -1)); else dst_p[0] = PIX(0, 0); if (TRISCAN_CMPYUV (( 1, 0), ( 0, -1))) dst_p[1] = Scale_Blend_11 (PIX(1, 0), PIX(0, -1)); else dst_p[1] = PIX(0, 0); if (TRISCAN_CMPYUV ((-1, 0), ( 0, 1))) dst_p[dlen] = Scale_Blend_11 (PIX(-1, 0), PIX(0, 1)); else dst_p[dlen] = PIX(0, 0); if (TRISCAN_CMPYUV (( 1, 0), ( 0, 1))) dst_p[dlen+1] = Scale_Blend_11 (PIX(1, 0), PIX(0, 1)); else dst_p[dlen+1] = PIX(0, 0); } else { dst_p[0] = PIX(0, 0); dst_p[1] = PIX(0, 0); dst_p[dlen] = PIX(0, 0); dst_p[dlen+1] = PIX(0, 0); } } } SCALE_(PlatDone) (); }
/** * Image labeling algorithm. * * @param im pointer to input image of type PIXEL * @param width width input image in pixels * @param height height input image in pixels * @param connectivty number of connectivity directions (4 or 8) * @param minsize smallest allowable blob size, they get subsumed into the parent blob * @param limage pointer to label image, of same size as \p im (output) * @param parent_out pointer to pointer for return of an array of region parents. Can be NULL. (output) * @param color_out pointer to pointer for return of an array of region color. Can be NULL. (output) * @param edge_out pointer to pointer for return of an array of region edge points. Can be NULL. (output) * @return the number of regions found */ static int ilabel(PIXEL *im, int width, int height, int connectivity, int minsize, LABEL *limage, LABEL **parent_out, PIXEL **color_out, unsigned int **edge_out) { int *blobsize, row, col, i, j, nlabels; int newlabel; LABEL *lmap2; LABEL prevlab, curlab; LABEL *parents; PIXEL curpix, prevpix; PIXEL *color; unsigned int *edge; int maxlabel = width*height; /* allocate label map and initialize to zero */ lmap = (LABEL *)mxCalloc(maxlabel, sizeof(LABEL)); /* region size */ blobsize = (int *)mxCalloc(maxlabel, sizeof(int)); if (parent_out) parents = (LABEL *)mxCalloc(maxlabel, sizeof(LABEL)); if (color_out) color = (PIXEL *)mxCalloc(maxlabel, sizeof(PIXEL)); if (edge_out) edge = (unsigned int *)mxCalloc(maxlabel, sizeof(unsigned int)); /* * Blob labels are ints >= 1 * newlabel holds the most recently assigned label value. * labels are unique and never recycled. * * When 2 blobs merge: A := A + B an entry is placed in the label map * lmap[B] = A indicating that all pixels that were B are now A. * If lmap[X] = 0 then X is unmerged, X is X * It is possible that a later merge: C = C + A * lmap[A] = C indicating that all As are now Cs * A pixel that was once B is mapped to A, then to C, but lmap[C] is 0 so * the indirection stops there. B --> A --> C * * Resolving the indirection is the job of lresolve() * lresolve(A) --> C * lresolve(B) --> C * lresolve(C) --> C */ for (row=0; row<height; row++) { for (col=0; col<width; col++) { curpix = PIX(im,row,col); #ifdef DEBUG printf("%2d ", curpix); #endif } #ifdef DEBUG printf("\n"); #endif } /* * first pass labelling loop. Only does 4-way connectivity */ newlabel = 0; for (row=0; row<height; row++) { prevlab = UNKNOWN; for (col=0; col<width; col++) { curpix = PIX(im,row,col); curlab = UNKNOWN; // start with no known label if (col > 0) { prevpix = PIX(im,row,col-1); /* if no change in pixel value then inherit label from left */ if (curpix == prevpix) curlab = prevlab; } #ifdef DEBUG printf("(%d,%d) cp=%d, pp=%d, cl=%d, pl=%d\n", row, col, curpix, prevpix, curlab, prevlab); #endif /* * check whether a label merge should happen, adjacent * pixels with the same value but different labels * means that one should change. * * merge can only happen on second row onwards */ if (row > 0) { if ( (PIX(im,row-1,col) == curpix) && (lresolve(PIX(limage,row-1,col)) != curlab) ) { /* we have a label assignment from N */ int newlabel; newlabel = lresolve(PIX(limage,row-1,col)); /* newlabel = PIX(lim,row-1,col); */ #ifdef DEBUG printf("mergeN(%d,%d): %d becomes %d: curpix=%d, prevpix=%d\n", row, col, curlab, newlabel, curpix, PIX(im,row-1,col)); #endif // newlabel dominates if (curlab != UNKNOWN) { lmap[curlab] = newlabel; blobsize[newlabel] += blobsize[curlab]; //if (edge[curlab] < edge[newlabel]) //edge[newlabel] = edge[curlab]; if (parents[curlab] == 0) parents[newlabel] = 0; } curlab = newlabel; } else if ( connectivity == 8 && (col > 0) && (PIX(im,row-1,col-1) == curpix) && (lresolve(PIX(limage,row-1,col-1)) != curlab) ) { // TODO: factorize these two merge cases /* we have a merge to NW */ int newlabel; newlabel = lresolve(PIX(limage,row-1,col-1)); /* newlabel = PIX(lim,row-1,col); */ #ifdef DEBUG printf("mergeNW(%d,%d): %d becomes %d\n", row, col, curlab, newlabel); #endif if (curlab != UNKNOWN) lmap[curlab] = newlabel; if (parents[curlab] == 0) parents[newlabel] = 0; //if (edge[curlab] < edge[newlabel]) //edge[newlabel] = edge[curlab]; blobsize[newlabel] += blobsize[curlab]; curlab = newlabel; } else if ( connectivity == 8 && (col < (width-1)) && (PIX(im,row-1,col+1) == curpix) && (lresolve(PIX(limage,row-1,col+1)) != curlab) ) { /* we have a merge to NE */ int newlabel; newlabel = lresolve(PIX(limage,row-1,col+1)); /* newlabel = PIX(lim,row-1,col); */ #ifdef DEBUG printf("mergeNE(%d,%d): %d becomes %d\n", row, col, curlab, newlabel); #endif if (curlab != UNKNOWN) lmap[curlab] = newlabel; blobsize[newlabel] += blobsize[curlab]; //if (edge[curlab] < edge[newlabel]) //edge[newlabel] = edge[curlab]; curlab = newlabel; } } if ((row > 0) && (col > 0)) { /* * check for enclosure */ int left, above, northwest; left = prevlab; above = lresolve( PIX(limage,row-1,col) ); northwest = lresolve( PIX(limage,row-1,col-1) ); if ( (left == curlab) && (above == curlab) && (northwest != curlab) ) { #ifdef DEBUG printf("(%d,%d): label %d encloses %d\n", row, col, curlab, northwest); #endif /* we have an enclosure */ if (blobsize[curlab] > THRESH) { // mark the parent of this blob parents[northwest] = curlab; //edge[northwest] = (row-1) + height*(col-1) + 1; //printf("edge is %d\n", edge[northwest]); } else { // it's a runt, merge it with its parent lmap[curlab] = northwest; } } } /* if label still not known, assign new */ if (curlab == UNKNOWN) { curlab = NEWLABEL; color[curlab] = curpix; edge[curlab] = row + height*col + 1; //printf("color %d %f\n", curlab, curpix); #ifdef DEBUG printf("new label(%d,%d): %d\n", row, col, curlab); #endif } blobsize[curlab] += 1; PIX(limage,row,col) = curlab; prevlab = curlab; prevpix = curpix; } } #ifdef DEBUG printf("max lim is %d\n", newlabel); #endif /* * The label indirection map can have have quite long chains of indirection * as the result of region merges. * * We pass over the map, and set each entry to its final value, or 0 meaning * that it is not indirected. * */ /* * create a new label map that maps all old labels to new consecutive labels */ lmap2 = (LABEL *)mxCalloc(newlabel+1, sizeof(LABEL)); /* * Create a vector of all the final label values, ie. lmap[i] == 0 */ #ifdef DEBUG printf("----------------------\nlmap:\n"); #endif for (i=1,nlabels=0; i<=newlabel; i++) { #ifdef DEBUG printf("(%d) = %d\n", i, lmap[i]); #endif if (lmap[i] == 0) lmap2[i] = ++nlabels; /* assign new sequential label */ } /* * now resolve each labels appear in the * labelled image, */ for (i=0; i<=newlabel; i++) if (lmap[i] != 0) { j = lresolve(i); lmap2[i] = lmap2[j]; } #ifdef DEBUG printf("----------------------\nlmap2:\n"); for (i=1; i<=newlabel; i++) printf("old(%d) -> %d\n", i, lmap2[i]); #endif #ifdef DEBUG printf("----------------------\nparents:\n"); for (i=1; i<=newlabel; i++) printf("parent[%d] = %d\n", i, parents[i]); #endif /* * resolve the labels in the parent array and assign to double proc * output array */ if (parent_out) { LABEL *lab; lab = mxCalloc(nlabels, sizeof(LABEL)); for (i=1; i<=newlabel; i++) { LABEL par = parents[i], child; if (par) { child = lmap2[i]; par = lmap2[par]; lab[child-1] = par; //printf("parent [%d] = %d\n", child, par); } } mxFree(parents); *parent_out = lab; } if (color_out || edge_out) { PIXEL *c; unsigned int *e; c = (PIXEL *)mxCalloc(nlabels, sizeof(PIXEL)); e = (unsigned int *)mxCalloc(nlabels, sizeof(unsigned int)); for (i=1; i<=newlabel; i++) { LABEL l; l = lmap2[i]; c[l-1] = color[i]; if (e[l-1] == 0) e[l-1] = edge[i]; //printf("edge %d %d %d\n", i, l, edge[i]); //printf("color [%d] = %f\n", l, color[i]); } if (color_out) { mxFree(color); *color_out = c; } if (edge_out) { mxFree(edge); *edge_out = e; } } /* * resolve the labels in the integer labelled image and assign * to the double prec. output image */ for (row=0; row<height; row++) for (col=0; col<width; col++) PIX(limage,row,col) = lmap2[ PIX(limage,row,col) ]; mxFree(lmap); mxFree(lmap2); mxFree(blobsize); return(nlabels); }
/****************************** scanimage ************************************ PROTO void scanimage(picstruct *field, picstruct *dfield, picstruct *ffield, picstruct *wfield, picstruct *dwfield) PURPOSE Scan of the large pixmap(s). Main loop and heart of the program. INPUT Measurement field pointer, Detection field pointer, Flag field pointer, Measurement weight-map field pointer, Detection weight-map field pointer, OUTPUT -. NOTES -. AUTHOR E. Bertin (IAP) VERSION 21/12/2011 ***/ void scanimage(picstruct *field, picstruct *dfield, picstruct **pffield, int nffield, picstruct *wfield, picstruct *dwfield) { static infostruct curpixinfo, *info, *store, initinfo, freeinfo, *victim; picstruct *ffield; checkstruct *check; objliststruct objlist; objstruct *cleanobj; pliststruct *pixel, *pixt; picstruct *cfield, *cdwfield; char *marker, newmarker, *blankpad, *bpt,*bpt0; int co, i,j, flag, luflag,pstop, xl,xl2,yl, cn, nposize, stacksize, w, h, blankh, maxpixnb, varthreshflag, ontotal; short trunflag; PIXTYPE thresh, relthresh, cdnewsymbol, cdwthresh,wthresh, *scan,*dscan,*cdscan,*dwscan,*dwscanp,*dwscann, *cdwscan,*cdwscanp,*cdwscann,*wscand, *scant, *wscan,*wscann,*wscanp; FLAGTYPE *pfscan[MAXFLAG]; status cs, ps, *psstack; int *start, *end, ymax; /* Avoid gcc -Wall warnings */ scan = dscan = cdscan = cdwscan = cdwscann = cdwscanp = dwscan = dwscann = dwscanp = wscan = wscann = wscanp = NULL; victim = NULL; /* Avoid gcc -Wall warnings */ blankh = 0; /* Avoid gcc -Wall warnings */ /*----- Beginning of the main loop: Initialisations */ thecat.ntotal = thecat.ndetect = 0; /* cfield is the detection field in any case */ cfield = dfield? dfield:field; /* cdwfield is the detection weight-field if available */ cdwfield = dwfield? dwfield:(prefs.dweight_flag?wfield:NULL); cdwthresh = cdwfield ? cdwfield->weight_thresh : 0.0; if (cdwthresh>BIG*WTHRESH_CONVFAC); cdwthresh = BIG*WTHRESH_CONVFAC; wthresh = wfield? wfield->weight_thresh : 0.0; /* If WEIGHTing and no absolute thresholding, activate threshold scaling */ varthreshflag = (cdwfield && prefs.thresh_type[0]!=THRESH_ABSOLUTE); relthresh = varthreshflag ? prefs.dthresh[0] : 0.0;/* To avoid gcc warnings*/ w = cfield->width; h = cfield->height; objlist.dthresh = cfield->dthresh; objlist.thresh = field->thresh; cfield->yblank = 1; field->y = field->stripy = 0; field->ymin = field->stripylim = 0; field->stripysclim = 0; if (dfield) { dfield->y = dfield->stripy = 0; dfield->ymin = dfield->stripylim = 0; dfield->stripysclim = 0; } if (nffield) for (i=0; i<nffield; i++) { ffield = pffield[i]; ffield->y = ffield->stripy = 0; ffield->ymin = ffield->stripylim = 0; ffield->stripysclim = 0; } if (wfield) { wfield->y = wfield->stripy = 0; wfield->ymin = wfield->stripylim = 0; wfield->stripysclim = 0; } if (dwfield) { dwfield->y = dwfield->stripy = 0; dwfield->ymin = dwfield->stripylim = 0; dwfield->stripysclim = 0; } /*Allocate memory for buffers */ stacksize = w+1; QMALLOC(info, infostruct, stacksize); QCALLOC(store, infostruct, stacksize); QMALLOC(marker, char, stacksize); QMALLOC(dumscan, PIXTYPE, stacksize); QMALLOC(psstack, status, stacksize); QCALLOC(start, int, stacksize); QMALLOC(end, int, stacksize); blankpad = bpt = NULL; lutzalloc(w,h); allocparcelout(); /* Some initializations */ thresh = objlist.dthresh; initinfo.pixnb = 0; initinfo.flag = 0; initinfo.firstpix = initinfo.lastpix = -1; for (xl=0; xl<stacksize; xl++) { marker[xl] = 0 ; dumscan[xl] = -BIG ; } co = pstop = 0; objlist.nobj = 1; curpixinfo.pixnb = 1; /* Init cleaning procedure */ initclean(); /*----- Allocate memory for the pixel list */ init_plist(); if (!(pixel = objlist.plist = malloc(nposize=prefs.mem_pixstack*plistsize))) error(EXIT_FAILURE, "Not enough memory to store the pixel stack:\n", " Try to decrease MEMORY_PIXSTACK"); /*----- at the beginning, "free" object fills the whole pixel list */ freeinfo.firstpix = 0; freeinfo.lastpix = nposize-plistsize; pixt = pixel; for (i=plistsize; i<nposize; i += plistsize, pixt += plistsize) PLIST(pixt, nextpix) = i; PLIST(pixt, nextpix) = -1; /* Allocate memory for other buffers */ if (prefs.filter_flag) { QMALLOC(cdscan, PIXTYPE, stacksize); if (cdwfield) { QCALLOC(cdwscan, PIXTYPE, stacksize); if (PLISTEXIST(wflag)) { QCALLOC(cdwscanp, PIXTYPE, stacksize); QCALLOC(cdwscann, PIXTYPE, stacksize); } } /*-- One needs a buffer to protect filtering if source-blanking applies */ if (prefs.blank_flag) { blankh = thefilter->convh/2+1; QMALLOC(blankpad, char, w*blankh); cfield->yblank -= blankh; if (dfield) field->yblank = cfield->yblank; bpt = blankpad; } } /*----- Here we go */ for (yl=0; yl<=h;) { ps = COMPLETE; cs = NONOBJECT; if (yl==h) { /*---- Need an empty line for Lutz' algorithm to end gracely */ if (prefs.filter_flag) { free(cdscan); if (cdwfield) { if (PLISTEXIST(wflag)) { free(cdwscanp); free(cdwscann); cdwscanp = cdwscan; } else free(cdwscan); } } cdwscan = cdwscann = cdscan = dumscan; } else { if (nffield) for (i=0; i<nffield; i++) { ffield = pffield[i]; pfscan[i] = (ffield->stripy==ffield->stripysclim)? (FLAGTYPE *)loadstrip(ffield, (picstruct *)NULL) : &ffield->fstrip[ffield->stripy*ffield->width]; } if (wfield) { /*------ Copy the previous weight line to track bad pixel limits */ wscan = (wfield->stripy==wfield->stripysclim)? (PIXTYPE *)loadstrip(wfield, (picstruct *)NULL) : &wfield->strip[wfield->stripy*wfield->width]; if (PLISTEXIST(wflag)) { if (yl>0) wscanp = &wfield->strip[((yl-1)%wfield->stripheight)*wfield->width]; if (yl<h-1) wscann = &wfield->strip[((yl+1)%wfield->stripheight)*wfield->width]; } } scan = (field->stripy==field->stripysclim)? (PIXTYPE *)loadstrip(field, wfield) : &field->strip[field->stripy*field->width]; if (dwfield) { dwscan = (dwfield->stripy==dwfield->stripysclim)? (PIXTYPE *)loadstrip(dwfield, dfield?(picstruct *)NULL:dwfield) : &dwfield->strip[dwfield->stripy*dwfield->width]; if (PLISTEXIST(wflag)) { if (yl>0) dwscanp = &dwfield->strip[((yl-1)%dwfield->stripheight) *dwfield->width]; if (yl<h-1) dwscann = &dwfield->strip[((yl+1)%dwfield->stripheight) *dwfield->width]; } } else { dwscan = wscan; if (PLISTEXIST(wflag)) { dwscanp = wscanp; dwscann = wscann; } } if (dfield) dscan = (dfield->stripy==dfield->stripysclim)? (PIXTYPE *)loadstrip(dfield, dwfield) : &dfield->strip[dfield->stripy*dfield->width]; else dscan = scan; if (prefs.filter_flag) { filter(cfield, cdscan, cfield->y); if (cdwfield) { if (PLISTEXIST(wflag)) { if (yl==0) filter(cdwfield, cdwscann, yl); wscand = cdwscanp; cdwscanp = cdwscan; cdwscan = cdwscann; cdwscann = wscand; if (yl < h-1) filter(cdwfield, cdwscann, yl + 1); } else filter(cdwfield, cdwscan, yl); } } else { cdscan = dscan; cdwscan = dwscan; if (PLISTEXIST(wflag)) { cdwscanp = dwscanp; cdwscann = dwscann; } } if ((check=prefs.check[CHECK_FILTERED])) writecheck(check, cdscan, w); } trunflag = (yl==0 || yl==h-1)? OBJ_TRUNC:0; for (xl=0; xl<=w; xl++) { if (xl == w) cdnewsymbol = -BIG; else cdnewsymbol = cdscan[xl]; newmarker = marker[xl]; marker[xl] = 0; curpixinfo.flag = trunflag; if (varthreshflag) thresh = relthresh*sqrt((xl==w || yl==h)? 0.0:cdwscan[xl]); luflag = cdnewsymbol > thresh?1:0; if (luflag) { if (xl==0 || xl==w-1) curpixinfo.flag |= OBJ_TRUNC; pixt = pixel + (cn=freeinfo.firstpix); freeinfo.firstpix = PLIST(pixt, nextpix); /*------- Running out of pixels, the largest object becomes a "victim" ------*/ if (freeinfo.firstpix==freeinfo.lastpix) { sprintf(gstr, "%d,%d", xl+1, yl+1); warning("Pixel stack overflow at position ", gstr); maxpixnb = 0; for (i=0; i<=w; i++) if (store[i].pixnb>maxpixnb) if (marker[i]=='S' || (newmarker=='S' && i==xl)) { flag = 0; if (i<xl) for (j=0; j<=co; j++) flag |= (start[j]==i); if (!flag) maxpixnb = (victim = &store[i])->pixnb; } for (j=1; j<=co; j++) if (info[j].pixnb>maxpixnb) maxpixnb = (victim = &info[j])->pixnb; if (!maxpixnb) error(EXIT_FAILURE, "*Fatal Error*: something is badly bugged in ", "scanimage()!"); if (maxpixnb <= 1) error(EXIT_FAILURE, "Pixel stack overflow in ", "scanimage()"); freeinfo.firstpix = PLIST(pixel+victim->firstpix, nextpix); PLIST(pixel+victim->lastpix, nextpix) = freeinfo.lastpix; PLIST(pixel+(victim->lastpix=victim->firstpix), nextpix) = -1; victim->pixnb = 1; victim->flag |= OBJ_OVERFLOW; } /*---------------------------------------------------------------------------*/ curpixinfo.lastpix = curpixinfo.firstpix = cn; PLIST(pixt, nextpix) = -1; PLIST(pixt, x) = xl; PLIST(pixt, y) = yl; PLIST(pixt, value) = scan[xl]; if (PLISTEXIST(dvalue)) PLISTPIX(pixt, dvalue) = dscan[xl]; if (PLISTEXIST(cdvalue)) PLISTPIX(pixt, cdvalue) = cdnewsymbol; if (PLISTEXIST(flag)) for (i=0; i<nffield; i++) PLISTFLAG(pixt, flag[i]) = pfscan[i][xl]; /*--------------------- Detect pixels with a low weight ---------------------*/ if (PLISTEXIST(wflag) && wscan) { PLISTFLAG(pixt, wflag) = 0; if (wscan[xl] >= wthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWWEIGHT; if (cdwscan[xl] >= cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (yl>0) { if (cdwscanp[xl] >= cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (xl>0 && cdwscanp[xl-1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (xl<w-1 && cdwscanp[xl+1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; } if (xl>0 && cdwscan[xl-1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (xl<w-1 && cdwscan[xl+1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (yl<h-1) { if (cdwscann[xl] >= cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (xl>0 && cdwscann[xl-1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; if (xl<w-1 && cdwscann[xl+1]>=cdwthresh) PLISTFLAG(pixt, wflag) |= OBJ_LOWDWEIGHT; } } if (PLISTEXIST(dthresh)) PLISTPIX(pixt, dthresh) = thresh; if (PLISTEXIST(var)) PLISTPIX(pixt, var) = wscan[xl]; if (cs != OBJECT) /*------------------------------- Start Segment -----------------------------*/ { cs = OBJECT; if (ps == OBJECT) { if (start[co] == UNKNOWN) { marker[xl] = 'S'; start[co] = xl; } else marker[xl] = 's'; } else { psstack[pstop++] = ps; marker[xl] = 'S'; start[++co] = xl; ps = COMPLETE; info[co] = initinfo; } } /*---------------------------------------------------------------------------*/ } if (newmarker) /*---------------------------- Process New Marker ---------------------------*/ { if (newmarker == 'S') { psstack[pstop++] = ps; if (cs == NONOBJECT) { psstack[pstop++] = COMPLETE; info[++co] = store[xl]; start[co] = UNKNOWN; } else update (&info[co],&store[xl], pixel); ps = OBJECT; } else if (newmarker == 's') { if ((cs == OBJECT) && (ps == COMPLETE)) { pstop--; xl2 = start[co]; update (&info[co-1],&info[co], pixel); if (start[--co] == UNKNOWN) start[co] = xl2; else marker[xl2] = 's'; } ps = OBJECT; } else if (newmarker == 'f') ps = INCOMPLETE; else if (newmarker == 'F') { ps = psstack[--pstop]; if ((cs == NONOBJECT) && (ps == COMPLETE)) { if (start[co] == UNKNOWN) { if ((int)info[co].pixnb >= prefs.ext_minarea) { sortit(field, dfield, wfield, cdwfield, &info[co], &objlist, cdwscan, wscan); } /* ------------------------------------ free the chain-list */ PLIST(pixel+info[co].lastpix, nextpix) = freeinfo.firstpix; freeinfo.firstpix = info[co].firstpix; } else { marker[end[co]] = 'F'; store[start[co]] = info[co]; } co--; ps = psstack[--pstop]; } } } /*---------------------------------------------------------------------------*/ if (luflag) update (&info[co],&curpixinfo, pixel); else { if (cs == OBJECT) /*-------------------------------- End Segment ------------------------------*/ { cs = NONOBJECT; if (ps != COMPLETE) { marker[xl] = 'f'; end[co] = xl; } else { ps = psstack[--pstop]; marker[xl] = 'F'; store[start[co]] = info[co]; co--; } } } if (prefs.blank_flag && xl<w) { if (prefs.filter_flag) *(bpt++) = (luflag)?1:0; else if (luflag) dscan[xl] = -BIG; if (dfield && luflag) scan[xl] = -BIG; } /*--------------------- End of the loop over the x's -----------------------*/ } /* Detected pixel removal at the end of each line */ if (prefs.blank_flag && yl<h) { if (prefs.filter_flag) { bpt = bpt0 = blankpad + w*((yl+1)%blankh); if (cfield->yblank >= 0) { scant = &PIX(cfield, 0, cfield->yblank); for (i=w; i--; scant++) if (*(bpt++)) *scant = -BIG; if (dfield) { bpt = bpt0; scant = &PIX(field, 0, cfield->yblank); for (i=w; i--; scant++) if (*(bpt++)) *scant = -BIG; } bpt = bpt0; } } cfield->yblank++; if (dfield) field->yblank = cfield->yblank; } /*-- Prepare markers for the next line */ yl++; field->stripy = (field->y=yl)%field->stripheight; if (dfield) dfield->stripy = (dfield->y=yl)%dfield->stripheight; if (nffield) for (i=0; i<nffield; i++) { ffield = pffield[i]; ffield->stripy = (ffield->y=yl)%ffield->stripheight; } if (wfield) wfield->stripy = (wfield->y=yl)%wfield->stripheight; if (dwfield) dwfield->stripy = (dwfield->y=yl)%dwfield->stripheight; /*-- Remove objects close to the ymin limit if ymin is ready to increase */ if (cfield->stripy==cfield->stripysclim) { cleanobj = cleanobjlist->obj+cleanobjlist->nobj-1; ontotal = 0; for (i=cleanobjlist->nobj; i--; cleanobj--) { if (cleanobj->ycmin <= cfield->ymin) { /*-------- Warn if there is a possibility for any aperture to be truncated */ if ((ymax=cleanobj->ycmax) > cfield->ymax) { sprintf(gstr, "Object at position %.0f,%.0f ", cleanobj->mx+1, cleanobj->my+1); QWARNING(gstr, "may have some apertures truncated:\n" " You might want to increase MEMORY_BUFSIZE"); } else if (ymax>cfield->yblank && prefs.blank_flag) { sprintf(gstr, "Object at position %.0f,%.0f ", cleanobj->mx+1, cleanobj->my+1); QWARNING(gstr, "may have some unBLANKed neighbours:\n" " You might want to increase MEMORY_PIXSTACK"); } if ((prefs.prof_flag && !(thecat.ntotal%10) && thecat.ntotal != ontotal) || !(thecat.ntotal%400)) NPRINTF(OUTPUT, "\33[1M> Line:%5d " "Objects: %8d detected / %8d sextracted\n\33[1A", yl>h? h:yl, thecat.ndetect, thecat.ntotal); ontotal = thecat.ntotal; endobject(field, dfield, wfield, cdwfield, i, cleanobjlist); subcleanobj(i); cleanobj = cleanobjlist->obj+i; /* realloc in subcleanobj() */ } } } if ((prefs.prof_flag && !(thecat.ntotal%10)) || !(yl%25)) NPRINTF(OUTPUT, "\33[1M> Line:%5d " "Objects: %8d detected / %8d sextracted\n\33[1A", yl>h?h:yl, thecat.ndetect, thecat.ntotal); /*--------------------- End of the loop over the y's -----------------------*/ } /* Removal or the remaining pixels */ if (prefs.blank_flag && prefs.filter_flag && (cfield->yblank >= 0)) for (j=blankh-1; j--; yl++) { bpt = bpt0 = blankpad + w*(yl%blankh); scant = &PIX(cfield, 0, cfield->yblank); for (i=w; i--; scant++) if (*(bpt++)) *scant = -BIG; if (dfield) { bpt = bpt0; scant = &PIX(field, 0, cfield->yblank); for (i=w; i--; scant++) if (*(bpt++)) *scant = -BIG; } cfield->yblank++; if (dfield) field->yblank = cfield->yblank; } /* Now that all "detected" pixels have been removed, analyse detections */ ontotal = 0; for (j=cleanobjlist->nobj; j--;) { if ((prefs.prof_flag && !(thecat.ntotal%10) && thecat.ntotal != ontotal) || !(thecat.ntotal%400)) NPRINTF(OUTPUT, "\33[1M> Line:%5d " "Objects: %8d detected / %8d sextracted\n\33[1A", h, thecat.ndetect, thecat.ntotal); ontotal = thecat.ntotal; endobject(field, dfield, wfield, cdwfield, 0, cleanobjlist); subcleanobj(0); } endclean(); /*Free memory */ if (prefs.filter_flag && cdwfield && PLISTEXIST(wflag)) free(cdwscanp); freeparcelout(); free(pixel); pixel = NULL; lutzfree(); free(info); info = NULL; free(store); store = NULL; free(marker); marker = NULL; free(dumscan); dumscan = NULL; free(psstack); psstack = NULL; free(start); start = NULL; free(end); end = NULL; if (prefs.blank_flag && prefs.filter_flag) free(blankpad); blankpad = NULL; return; }
/** interpolateBiCub: bi-cubic interpolation function using 4x4 pixel, see interpolate */ void _FLT(interpolateBiCub)(unsigned char *rv, float x, float y, unsigned char* img, int width, int height, unsigned char def) { // do a simple linear interpolation at the border if (x < 1 || x > width - 2 || y < 1 || y > height - 2) { _FLT(interpolateBiLinBorder)(rv, x,y,img,width,height,def); } else { int x_f = myfloor(x); int y_f = myfloor(y); float tx = x-x_f; short v1 = _FLT(bicub_kernel)(tx, PIX(img, x_f-1, y_f-1, width, height), PIX(img, x_f, y_f-1, width, height), PIX(img, x_f+1, y_f-1, width, height), PIX(img, x_f+2, y_f-1, width, height)); short v2 = _FLT(bicub_kernel)(tx, PIX(img, x_f-1, y_f, width, height), PIX(img, x_f, y_f, width, height), PIX(img, x_f+1, y_f, width, height), PIX(img, x_f+2, y_f, width, height)); short v3 = _FLT(bicub_kernel)(tx, PIX(img, x_f-1, y_f+1, width, height), PIX(img, x_f, y_f+1, width, height), PIX(img, x_f+1, y_f+1, width, height), PIX(img, x_f+2, y_f+1, width, height)); short v4 = _FLT(bicub_kernel)(tx, PIX(img, x_f-1, y_f+2, width, height), PIX(img, x_f, y_f+2, width, height), PIX(img, x_f+1, y_f+2, width, height), PIX(img, x_f+2, y_f+2, width, height)); *rv = (unsigned char)_FLT(bicub_kernel)(y-y_f, v1, v2, v3, v4); } }
static void edge (GimpDrawable *drawable) { GimpPixelRgn src_rgn, dest_rgn; gpointer pr; GimpPixelFetcher *pft; guchar *srcrow, *src; guchar *destrow, *dest; guchar pix00[4], pix01[4], pix02[4]; guchar pix10[4], pix11[4], pix12[4]; guchar pix20[4], pix21[4], pix22[4]; glong width, height; gint alpha; gboolean has_alpha; gint chan; gint x, y; gint x1, y1, x2, y2; gint maxval; gint cur_progress; gint max_progress; gdouble per_progress; if (evals.amount < 1.0) evals.amount = 1.0; pft = gimp_pixel_fetcher_new (drawable, FALSE); gimp_pixel_fetcher_set_edge_mode (pft, evals.wrapmode); gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); width = gimp_drawable_width (drawable->drawable_id); height = gimp_drawable_height (drawable->drawable_id); alpha = gimp_drawable_bpp (drawable->drawable_id); has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); if (has_alpha) alpha--; maxval = 255; cur_progress = 0; per_progress = 0.0; max_progress = (x2 - x1) * (y2 - y1) / 100; gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, x2-x1, y2-y1, FALSE, FALSE); gimp_pixel_rgn_init (&dest_rgn, drawable, x1, y1, x2-x1, y2-y1, TRUE, TRUE); for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn); pr != NULL; pr = gimp_pixel_rgns_process (pr)) { srcrow = src_rgn.data; destrow = dest_rgn.data; for (y = dest_rgn.y; y < (dest_rgn.y + dest_rgn.h); y++, srcrow += src_rgn.rowstride, destrow += dest_rgn.rowstride) { src = srcrow; dest = destrow; for (x = dest_rgn.x; x < (dest_rgn.x + dest_rgn.w); x++, src += src_rgn.bpp, dest += dest_rgn.bpp) { if (dest_rgn.x < x && x < dest_rgn.x + dest_rgn.w - 2 && dest_rgn.y < y && y < dest_rgn.y + dest_rgn.h - 2) { /* * 3x3 kernel is inside of the tile -- do fast * version */ for (chan = 0; chan < alpha; chan++) { /* get the 3x3 kernel into a guchar array, * and send it to edge_detect */ guchar kernel[9]; gint i,j; #define PIX(X,Y) src[ (Y-1)*(int)src_rgn.rowstride + (X-1)*(int)src_rgn.bpp + chan ] /* make convolution */ for(i = 0; i < 3; i++) for(j = 0; j < 3; j++) kernel[3*i + j] = PIX(i,j); #undef PIX dest[chan] = edge_detect (kernel); } } else { /* * The kernel is not inside of the tile -- do slow * version */ gimp_pixel_fetcher_get_pixel (pft, x-1, y-1, pix00); gimp_pixel_fetcher_get_pixel (pft, x , y-1, pix10); gimp_pixel_fetcher_get_pixel (pft, x+1, y-1, pix20); gimp_pixel_fetcher_get_pixel (pft, x-1, y , pix01); gimp_pixel_fetcher_get_pixel (pft, x , y , pix11); gimp_pixel_fetcher_get_pixel (pft, x+1, y , pix21); gimp_pixel_fetcher_get_pixel (pft, x-1, y+1, pix02); gimp_pixel_fetcher_get_pixel (pft, x , y+1, pix12); gimp_pixel_fetcher_get_pixel (pft, x+1, y+1, pix22); for (chan = 0; chan < alpha; chan++) { guchar kernel[9]; kernel[0] = pix00[chan]; kernel[1] = pix01[chan]; kernel[2] = pix02[chan]; kernel[3] = pix10[chan]; kernel[4] = pix11[chan]; kernel[5] = pix12[chan]; kernel[6] = pix20[chan]; kernel[7] = pix21[chan]; kernel[8] = pix22[chan]; dest[chan] = edge_detect (kernel); } } if (has_alpha) dest[alpha] = src[alpha]; } } cur_progress += dest_rgn.w * dest_rgn.h; if (cur_progress > max_progress) { cur_progress = cur_progress - max_progress; per_progress = per_progress + 0.01; gimp_progress_update (per_progress); } } gimp_progress_update (1.0); gimp_pixel_fetcher_destroy (pft); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1)); }
void detect_edges(Image *img, float sigma, float threshold, \ unsigned char *edge_pix, PList *edge_pts) { int x, y; int w = img->w; int h = img->h; // convert image to grayscale float **gray = array_create(w, h); convert_grayscale(img, gray); // blur grayscale image float **gray2 = array_create(w, h); gaussian_blur(gray, gray2, w, h, sigma); // compute gradient of blurred image float **g_mag = array_create(w, h); float **g_ang = array_create(w, h); compute_gradient(gray2, w, h, g_mag, g_ang); // mark edge pixels #define PIX(y,x) edge_pix[(y)*w+(x)] #pragma omp parallel { #pragma omp for private(x) nowait for (y = 0; y < h; y++) for (x = 0; x < w; x++) { PIX(y,x) = is_edge(g_mag,g_ang,threshold,x,y,w,h) ? 255 : 0; } // connect horizontal edges #pragma omp for private(x) nowait for (y = 0; y < h ; y++) for (x = 1; x < w-1; x++) { if (!PIX(y,x) && PIX(y,x+1) && PIX(y,x-1)) PIX(y,x) = 255; } // connect vertical edges #pragma omp for private(y) nowait for (x = 0; x < w ; x++) for (y = 1; y < h-1; y++) { if (!PIX(y,x) && PIX(y+1,x) && PIX(y-1,x)) PIX(y,x) = 255; } #pragma omp for private(x) // connect diagonal edges for (y = 1; y < h-1; y++) for (x = 1; x < w-1; x++) { if (!PIX(y,x) && PIX(y-1,x-1) && PIX(y+1,x+1)) PIX(y,x) = 255; if (!PIX(y,x) && PIX(y-1,x+1) && PIX(y+1,x-1)) PIX(y,x) = 255; } } // add edge points to list if (edge_pts) { for (y = 0; y < h; y++) for (x = 0; x < w; x++) { if (PIX(y,x)) PList_push(edge_pts, x, y); } } // cleanup array_free(g_mag, h); array_free(g_ang, h); array_free(gray2, h); array_free(gray, h); }
static int GetPSF (char *name, Hdr *phdr, double xsize, double ysize, ScatterFunctions *scf, Image *psf1, Image *psf2, Image *psf3) { /* char *name; i: name of TELTAB reference file Hdr *phdr i: primary header double xsize, ysize; i: aperture size in arcsec ScatterFunctions *scf; o: data structure with scattering functions Image *psf1,2,3; o: PSF images, previously initialized */ IRAFPointer tp; IRAFPointer cp_refwave, cp_pscale, cp_psfdim, cp_telepsf; int row, nrows, psfdim; double rw, psfscale; Image ospsf; Image imtemp, psf; char keyword[STIS_CBUF]; double xplate, yplate; double sbox, lbox; double rstart, rstop; double frac1, frac2; float fhold; double sum; int i, j, k, kk, ms, ml, ns, nl, s, l; int ns2, nl2, s1, s2, l1, l2; int istart, istop; int status; int Alloc1DImage (Image *, int); int Alloc2DImage (Image *, int, int); void InitImage (Image *); void FreeImage (Image *); /* Define plate scale. */ if (streq_ic (scf->opt_elem, "E140M")) xplate = 0.036; else if (streq_ic (scf->opt_elem, "E140H")) xplate = 0.0466; else if (streq_ic (scf->opt_elem, "E230M")) xplate = 0.033; else if (streq_ic (scf->opt_elem, "E230H")) xplate = 0.0466; else { printf ("Non supported grating.\n"); return (ERROR_RETURN); } yplate = 0.029; /* Truncate the aperture size if it extends beyond the borders of an image. */ /* See if uniformly illuminated aperture was used. */ if ((status = Get_KeyS (phdr, "SCLAMP", 0, "", keyword, STIS_CBUF))) return (status); if (!streq_ic (keyword, "NONE")) { ml = (int)floor (ysize / yplate); if (ml % 2) { status = Alloc1DImage (psf1, ml+1); status |= Alloc1DImage (psf2, ml+1); status |= Alloc1DImage (psf3, ml+1); if (status) return (status); for (i = 1; i < ml; i++) { psf1->pix[i] = 1.0 / ml; psf2->pix[i] = 1.0 / ml; psf3->pix[i] = 1.0 / ml; } psf1->pix[0] = 0.5 / ml; psf1->pix[ml] = 0.5 / ml; psf2->pix[0] = 0.5 / ml; psf2->pix[ml] = 0.5 / ml; psf3->pix[0] = 0.5 / ml; psf3->pix[ml] = 0.5 / ml; } else { status = Alloc1DImage (psf1, ml); status |= Alloc1DImage (psf2, ml); status |= Alloc1DImage (psf3, ml); if (status) return (status); for (i = 0; i < ml; i++) { psf1->pix[i] = 1.0 / ml; psf2->pix[i] = 1.0 / ml; psf3->pix[i] = 1.0 / ml; } } return (STIS_OK); } /* Scan reference file and process each PSF. */ tp = c_tbtopn (name, IRAF_READ_ONLY, 0); if (c_iraferr()) { printf ("ERROR TELTAB `%s' not found\n", name); return (OPEN_FAILED); } nrows = c_tbpsta (tp, TBL_NROWS); c_tbcfnd1 (tp, "PSFWAVE", &cp_refwave); c_tbcfnd1 (tp, "PSCALE", &cp_pscale); c_tbcfnd1 (tp, "PSFDIM", &cp_psfdim); c_tbcfnd1 (tp, "TELEPSF", &cp_telepsf); if (cp_refwave == 0 || cp_psfdim == 0 || cp_pscale == 0 || cp_telepsf == 0) { printf( "ERROR Column not found in TELTAB\n"); c_tbtclo (tp); return (COLUMN_NOT_FOUND); } kk = 0; for (row = 1; row <= nrows ; row++) { c_tbegtd (tp, cp_refwave, row, &rw); if (c_iraferr()) return (TABLE_ERROR); /* Matching reference wavelenghts. */ if (rw == scf->psfw[kk]) { /* Read PSF image and associated data. */ c_tbegtd (tp, cp_pscale, row, &psfscale); c_tbegti (tp, cp_psfdim, row, &psfdim); InitImage (&imtemp); if ((status = Alloc2DImage (&imtemp, psfdim, psfdim))) return (status); i = c_tbagtr (tp, cp_telepsf, row, imtemp.pix, 1, imtemp.npix); if (c_iraferr()) return (TABLE_ERROR); /* Find peak. */ ns = imtemp.nx; nl = imtemp.ny; fhold = -FLT_MAX; for (i = 0; i < ns; i++) { for (j = 0; j < nl; j++) { if (PIX (imtemp, i, j) > fhold) { s = i; l = j; fhold = PIX (imtemp, i, j); } } } /* Determine portion of PSF that made it through aperture. */ ns2 = ((int)NINT (xsize / psfscale)) / 2; nl2 = ((int)NINT (ysize / psfscale)) / 2; s1 = ((s - ns2) >= 0) ? (s - ns2) : 0; s2 = ((s + ns2) <= (ns - 1)) ? (s + ns2) : (ns - 1); l1 = ((l - nl2) >= 0) ? (l - nl2) : 0; l2 = ((l + nl2) <= (nl - 1)) ? (l + nl2) : (nl - 1); /* Extract sub-image. */ InitImage (&ospsf); if ((status = Alloc2DImage (&ospsf, s2 - s1 + 1, l2 - l1 + 1))) return (status); k = 0; /* location of braces looks like a typo, but harmless */ for (j = l1; j <= l2; j++) for (i = s1; i <= s2; i++) { ospsf.pix[k++] = PIX (imtemp, i, j); } FreeImage (&imtemp); ns = ospsf.nx; nl = ospsf.ny; /* # of STIS pixels (ms*ml) illuminated by aperture. */ /* modified on 2013 Nov 13 by PEH xplate / psfscale and yplate / psfscale are the factors by which the PSF in the _tel.fits file are oversampled. */ ms = (NINT (ns / (xplate / psfscale))) / 2; ml = (NINT (nl / (yplate / psfscale))) / 2; ms = 2 * ms + 1; ml = 2 * ml + 1; /* Bin oversampled PSF to STIS pixel scale. */ /* Bin columns. */ if ((status = Alloc2DImage (&imtemp, ms, nl))) return (status); sbox = ns / (double)ms; for (i = 0; i < ms; i++) { rstart = i * sbox; rstop = (i+1) * sbox; istart = (int) floor (rstart); istop = (int) floor (rstop); istop = (istop < ns) ? istop : ns-1; frac1 = rstart - istart; frac2 = 1.0 - (rstop - istop); for (j = 0; j < nl; j++) { for (k = istart+1; k < istop; PIX (imtemp, i, j) += PIX (ospsf, k++, j)); PIX (imtemp, i, j) += PIX (ospsf, istart, j) * (1.0 - frac1); PIX (imtemp, i, j) += PIX (ospsf, istop, j) * (1.0 - frac2); } } FreeImage (&ospsf); /* Bin rows. */ InitImage (&psf); if ((status = Alloc2DImage (&psf, ms, ml))) return (status); lbox = nl / (double)ml; for (j = 0; j < ml; j++) { rstart = j * lbox; rstop = (j+1) * lbox; istart = (int) floor (rstart); istop = (int) floor (rstop); istop = (istop < nl) ? istop : nl-1; frac1 = rstart - istart; frac2 = 1.0 - (rstop - istop); for (i = 0; i < ms; i++) { for (k = istart+1; k < istop; PIX (psf, i, j) += PIX (imtemp, i, k++)); PIX (psf, i, j) += PIX (imtemp, i, istart) * (1.0 - frac1); PIX (psf, i, j) += PIX (imtemp, i, istop) * (1.0 - frac2); } } FreeImage (&imtemp); /* Normalize PSF to unit area. */ sum = 0.0; for (i = 0; i < psf.npix; sum += psf.pix[i++]); for (i = 0; i < psf.npix; psf.pix[i++] /= sum); /* This awful code is a consequence of the change in reference file format that took place after the original code was completed. */ switch (kk) { case 0: if ((status = Alloc2DImage (psf1, psf.nx, psf.ny))) return (status); for (i= 0 ; i < psf1->npix; i++) psf1->pix[i] = psf.pix[i]; break; case 1: if ((status = Alloc2DImage (psf2, psf.nx, psf.ny))) return (status); for (i= 0 ; i < psf2->npix; i++) psf2->pix[i] = psf.pix[i]; break; case 2: if ((status = Alloc2DImage (psf3, psf.nx, psf.ny))) return (status); for (i= 0 ; i < psf3->npix; i++) psf3->pix[i] = psf.pix[i]; break; default: break; } FreeImage (&psf); kk++; } } if (kk == 0) { printf ("ERROR No matching rows in TELTAB `%s'\n", name); return (TABLE_ERROR); } c_tbtclo (tp); return (STIS_OK); }