Ejemplo n.º 1
0
bool BinaryImage::label()
{
	OSC_ERR err;
	
	if((err = OscVisLabelBinary(&this->getOscarContext(), &this->getRegions())) != SUCCESS)
	{
		return false;
	}
	
	if((err = OscVisGetRegionProperties(&this->getRegions())) != SUCCESS)
	{
		return false;
	}
	
	return true;
}
Ejemplo n.º 2
0
void ProcessFrame(uint8 *pInputImg) {
	int c, r;
	int nc = OSC_CAM_MAX_IMAGE_WIDTH / 2;
	int siz = sizeof(data.u8TempImage[GRAYSCALE]);

	int Shift = 7;
	short Beta = 2;//the meaning is that in floating point the value of Beta is = 6/(1 << Shift) = 6/128 = 0.0469
	uint8 MaxForeground = 120;//the maximum foreground counter value (at 15 fps this corresponds to less than 10s)

	struct OSC_PICTURE Pic1, Pic2;//we require these structures to use Oscar functions
	struct OSC_VIS_REGIONS ImgRegions;//these contain the foreground objects

	if (data.ipc.state.nStepCounter == 1) {
		/* this is the first time we call this function */
		/* first time we call this; index 1 always has the background image */
		memcpy(data.u8TempImage[BACKGROUND], data.u8TempImage[GRAYSCALE],
				sizeof(data.u8TempImage[GRAYSCALE]));
		/* set foreground counter to zero */
		memset(data.u8TempImage[FGRCOUNTER], 0,
				sizeof(data.u8TempImage[FGRCOUNTER]));
	} else {
		/* this is the default case */
		uint32 Hist[256];
		uint8* p = &data.u8TempImage[GRAYSCALE][0];
		memset(Hist, 0, sizeof(Hist));
		uint32 w0 = 0;
		uint32 w1 = 0;
		uint32 m0 = 0;
		uint32 m1 = 0;
		float roh2 = 0;
		float roh2_actual = 0;
		uint8 k_best = 0;
		int i1,k,g;

		// a) loop over image
		for (i1=0;i1<siz;i1++)
			Hist[p[i1]] += 1;

		// b) find best k
		for (k = 0; k <= 255; k++) // main loop over K
		{
			for (g=0, w0=0, m0=0; g<=k; g++) { // loop from 0 to K
				w0 += Hist[g];
				m0 += Hist[g] * g;
			}
			for (g=k+1, w1=0, m1=0; g<=255; g++) { // loop from K+1 to 255
				w1 += Hist[g];
				m1 += Hist[g] * g;
			}
			roh2_actual = ((float)w0*w1) * ( (((float)m0/w0) - ((float)m1/w1)) * (((float)m0/w0) - ((float)m1/w1)) );
			if (roh2_actual > roh2) // evaluate maximum value of roh for best K
			{
				roh2 = roh2_actual;
				k_best = k;
			}
		}
		// write actual value of 'K' to index.xhtml
		data.ipc.state.actualK = k_best;

		/* apply threshold value 'k' to threshold image */
		for (r = 0; r < siz; r += nc)/* we strongly rely on the fact that them images have the same size */
		{
			for (c = 0; c < nc; c++) {

				/* determine the foreground estimate */
				data.u8TempImage[THRESHOLD][r + c]
						= data.u8TempImage[GRAYSCALE][r + c] > k_best ? 0
								: 0xff;
			}
		}

		/*
		 {
		 //for debugging purposes we log the background values to console out
		 //we chose the center pixel of the image (adaption to other pixel is straight forward)
		 int offs = nc*(OSC_CAM_MAX_IMAGE_HEIGHT/2)/2+nc/2;

		 OscLog(INFO, "%d %d %d %d %d\n", (int) data.u8TempImage[GRAYSCALE][offs], (int) data.u8TempImage[BACKGROUND][offs], (int) data.u8TempImage[BACKGROUND][offs]-data.ipc.state.nThreshold,
		 (int) data.u8TempImage[BACKGROUND][offs]+data.ipc.state.nThreshold, (int) data.u8TempImage[FGRCOUNTER][offs]);
		 }
		 */

		for (r = nc; r < siz - nc; r += nc)/* we skip the first and last line */
		{
			for (c = 1; c < nc - 1; c++)/* we skip the first and last column */
			{
				unsigned char* p = &data.u8TempImage[THRESHOLD][r + c];
				data.u8TempImage[EROSION][r + c] = *(p - nc - 1) & *(p - nc)
						& *(p - nc + 1) & *(p - 1) & *p & *(p + 1) & *(p + nc
						- 1) & *(p + nc) & *(p + nc + 1);
			}
		}

		for (r = nc; r < siz - nc; r += nc)/* we skip the first and last line */
		{
			for (c = 1; c < nc - 1; c++)/* we skip the first and last column */
			{
				unsigned char* p = &data.u8TempImage[EROSION][r + c];
				data.u8TempImage[DILATION][r + c] = *(p - nc - 1) | *(p - nc)
						| *(p - nc + 1) | *(p - 1) | *p | *(p + 1) | *(p + nc
						- 1) | *(p + nc) | *(p + nc + 1);
			}
		}

		//wrap image DILATION in picture struct
		Pic1.data = data.u8TempImage[DILATION];
		Pic1.width = nc;
		Pic1.height = OSC_CAM_MAX_IMAGE_HEIGHT / 2;
		Pic1.type = OSC_PICTURE_GREYSCALE;
		//as well as EROSION (will be used as output)
		Pic2.data = data.u8TempImage[EROSION];
		Pic2.width = nc;
		Pic2.height = OSC_CAM_MAX_IMAGE_HEIGHT / 2;
		Pic2.type = OSC_PICTURE_BINARY;//probably has no consequences
		//have to convert to OSC_PICTURE_BINARY which has values 0x01 (and not 0xff)
		OscVisGrey2BW(&Pic1, &Pic2, 0x80, false);

		//now do region labeling and feature extraction
		OscVisLabelBinary(&Pic2, &ImgRegions);
		OscVisGetRegionProperties(&ImgRegions);

		//OscLog(INFO, "number of objects %d\n", ImgRegions.noOfObjects);
		//plot bounding boxes both in gray and dilation image
		Pic2.data = data.u8TempImage[GRAYSCALE];
		OscVisDrawBoundingBoxBW(&Pic2, &ImgRegions, 255);
		OscVisDrawBoundingBoxBW(&Pic1, &ImgRegions, 128);
	}
}
Ejemplo n.º 3
0
void ProcessFrame(uint8 *pInputImg)
{
	int c, r;
	int nc = OSC_CAM_MAX_IMAGE_WIDTH/2;
	int siz = sizeof(data.u8TempImage[GRAYSCALE]);
	short thresh;

	struct OSC_PICTURE Pic1, Pic2;//we require these structures to use Oscar functions
	struct OSC_VIS_REGIONS ImgRegions;//these contain the foreground objects

	if(data.ipc.state.nThreshold==0){
		uint32 hist[256];
		uint32 histMean[256];
		uint32 Wtot,Mtot;
		uint8* p=data.u8TempImage[GRAYSCALE];

		memset(hist,0,sizeof(hist));
		for(int i=0;i<siz;i++){
			hist[p[i]]++;
		}
		Wtot=siz;
		Mtot=0;
		memset(histMean,0,sizeof(hist));
		for(int i=0;i<256;i++){
			histMean[i]=hist[i]*i;
			Mtot+=histMean[i];
		}

		float sigmaMax=0,t;
		int32 W0,W1,M0,M1,k,Wsum,Msum;
		Wsum=Msum=0;
		for(k=0;k<256;k++){
			W0=W1=M0=M1=0;
			Wsum+=hist[k];
			W0=Wsum;
			Msum+=histMean[k];
			M0=Msum;
			W1=Wtot-W0;
			M1=Mtot-M0;
			M0=(int32)((float)M0/(float)W0);
			M1=(int32)((float)M1/(float)W1);
			M0=M0-M1;
			t=((float)M0)*((float)M0)*((float)W0)*((float)W1);
			if(t>sigmaMax){
				thresh=k;
				sigmaMax=t;
			}
		}
	}else{
		thresh=data.ipc.state.nThreshold*255/100;
	}


	/* this is the default case */
	for(r = 0; r < siz; r+= nc)/* we strongly rely on the fact that them images have the same size */
	{
		for(c = 0; c < nc; c++)
		{
			/* first determine the foreground estimate */
			data.u8TempImage[THRESHOLD][r+c]=abs((short)data.u8TempImage[GRAYSCALE][r+c])>thresh ? 0:255;
		}
	}

	for(r = nc; r < siz-nc; r+= nc)/* we skip the first and last line */
	{
		for(c = 1; c < nc-1; c++)/* we skip the first and last column */
		{
			unsigned char* p = &data.u8TempImage[THRESHOLD][r+c];
			data.u8TempImage[DILATION][r+c] = *(p-nc-1) | *(p-nc) | *(p-nc+1) |
											  *(p-1)    | *p      | *(p+1)    |
											  *(p+nc-1) | *(p+nc) | *(p+nc+1);
		}
	}

	for(r = nc; r < siz-nc; r+= nc)/* we skip the first and last line */
	{
		for(c = 1; c < nc-1; c++)/* we skip the first and last column */
		{
			unsigned char* p = &data.u8TempImage[DILATION][r+c];
			data.u8TempImage[EROSION][r+c] = *(p-nc-1) & *(p-nc) & *(p-nc+1) &
											 *(p-1)    & *p      & *(p+1)    &
											 *(p+nc-1) & *(p+nc) & *(p+nc+1);
		}
	}

	//wrap image DILATION in picture struct
	Pic1.data = data.u8TempImage[DILATION];
	Pic1.width = nc;
	Pic1.height = OSC_CAM_MAX_IMAGE_HEIGHT/2;
	Pic1.type = OSC_PICTURE_GREYSCALE;
	//as well as EROSION (will be used as output)
	Pic2.data = data.u8TempImage[EROSION];
	Pic2.width = nc;
	Pic2.height = OSC_CAM_MAX_IMAGE_HEIGHT/2;
	Pic2.type = OSC_PICTURE_BINARY;//probably has no consequences
	//have to convert to OSC_PICTURE_BINARY which has values 0x01 (and not 0xff)
	OscVisGrey2BW(&Pic1, &Pic2, 0x80, false);

	//now do region labeling and feature extraction
	OscVisLabelBinary( &Pic2, &ImgRegions);
	OscVisGetRegionProperties( &ImgRegions);

	//OscLog(INFO, "number of objects %d\n", ImgRegions.noOfObjects);
	//plot bounding boxes both in gray and dilation image
	Pic2.data = data.u8TempImage[GRAYSCALE];
	OscVisDrawBoundingBoxBW( &Pic2, &ImgRegions, 255);
	OscVisDrawBoundingBoxBW( &Pic1, &ImgRegions, 128);
}
Ejemplo n.º 4
0
static void region_labeling(uint8_t* dst)
{
  uint8_t tmp_buf[SZ];
  
  /* input picture info */
  struct OSC_PICTURE picin =
  {
    .data = IMAGE(DILATION),
    .width = NC,
    .height = OSC_CAM_MAX_IMAGE_HEIGHT / 2u,
    .type = OSC_PICTURE_GREYSCALE
  };

  /* temporary binary image */
  struct OSC_PICTURE picout =
  {
    .data = tmp_buf,
    .width = NC,
    .height = OSC_CAM_MAX_IMAGE_HEIGHT / 2u,
    .type = OSC_PICTURE_BINARY
  };
  
  /* region labeling info */
  struct OSC_VIS_REGIONS region_info;
  
  /* make a binary image */
  OscVisGrey2BW(&picin, &picout, 0x80, false);
  
  /* now do the region labeling */
  OscVisLabelBinary(&picout, &region_info);
  
  /* feature extraction */
  OscVisGetRegionProperties(&region_info);
  
  /* now copy the grayscale image to the labeling image */
  memcpy(dst, IMAGE(GRAYSCALE), SZ);
  
  /* abuse the picin picture info to draw the bounding boxes */
  picin.data = dst;
  draw_bbox(&picin, &region_info, 0x80);
  
  /* set the number of objects in the web gui */
  data.ipc.state.objectcount = region_info.noOfObjects;
}

static uint8_t otsu(const uint8_t* img)
{
  uint8_t ret;
  uint32_t histogram[256];
  uint32_t k, g;
  uint32_t w0, w1;
  uint32_t mu0s, mu1s;
  float mu0, mu1;
  float sigma_b, sigma_max;

  /* initialise the histogram with zero */
  memset(histogram, 0, sizeof(histogram));

  /* calculate the histogram */
  imhist(histogram, img);
  
  sigma_max = 0.0f;
  
  for(k = 0; k < 256; k++)
  {
    w0 = w1 = 0;
    mu0s = mu1s = 0;
    for(g = 0; g < 256; g++)
    {
      if(g <= k)
      {
        w0 += histogram[g];
        mu0s += histogram[g] * g;
      }
      else
      {
        w1 += histogram[g];
        mu1s += histogram[g] * g;
      }
    }
    mu0 = ((float)mu0s / (float)w0);
    mu1 = ((float)mu1s / (float)w1);
    
    sigma_b = ((float)(w0 * w1)) * (mu0 - mu1) * (mu0 - mu1);
    if(sigma_b > sigma_max)
    {
      sigma_max = sigma_b;
      ret = (uint8_t)k;
    }
  }
  
  return ret;
}