Exemplo n.º 1
0
unsigned int floodfill(image img, int px, int py,
	       rgb_color_p bankscolor,
	       rgb_color_p rcolor)
{
  _ffill_queue head;
  rgb_color thisnode;
  unsigned int pixelcount = 0;
  double tolerance = 0.05;

  if ( (px < 0) || (py < 0) || (px >= img->width) || (py >= img->height) )
    return;

  TAILQ_INIT(&head);

  _ffill_rgbcolor(img, &thisnode, px, py);
  if ( color_distance(&thisnode, bankscolor) <= tolerance ) return;

  _ffill_enqueue(&head, px, py);
  while( head.tqh_first != NULL ) {
    _ffill_node_t *n = head.tqh_first;
    _ffill_rgbcolor(img, &thisnode, n->px, n->py);
    if ( color_distance(&thisnode, bankscolor) > tolerance ) {
      put_pixel_unsafe(img, n->px, n->py, rcolor->red, rcolor->green, rcolor->blue);
      pixelcount++;
    }
    int tx = n->px, ty = n->py;
    _ffill_removehead(&head);
    NSOE(tx - 1, ty);
    NSOE(tx + 1, ty);
    NSOE(tx, ty - 1);
    NSOE(tx, ty + 1);
  }
  return pixelcount;
}
Exemplo n.º 2
0
static inline int find_nearest_color(struct rgb *r, int l)
{
	int dist, dst, min, i;
	static struct rgb_cache_entry rgb_cache[RGB_HASH_SIZE];
	static int cache_init = 0;
	int h;
	if (!cache_init) goto initialize;
	back:
	h = HASH_RGB(r, l);
	if (rgb_cache[h].color != -1 && rgb_cache[h].l == l && rgb_cache[h].rgb.r == r->r && rgb_cache[h].rgb.g == r->g && rgb_cache[h].rgb.b == r->b) return rgb_cache[h].color;
	dist = 0xffffff;
	min = 0;
	for (i = 0; i < l; i++) if ((dst = color_distance(r, &palette[i])) < dist)
		dist = dst, min = i;
	rgb_cache[h].color = min;
	rgb_cache[h].l = l;
	rgb_cache[h].rgb.r = r->r;
	rgb_cache[h].rgb.g = r->g;
	rgb_cache[h].rgb.b = r->b;
	return min;

	initialize:
	for (h = 0; h < RGB_HASH_SIZE; h++) rgb_cache[h].color = -1;
	cache_init = 1;
	goto back;
}
void DenseSegmentation::AddFrameToSegmentationFromFeatures(
    const std::vector<cv::Mat>& curr_features,
    const SegmentationDesc* constrained_segmentation) {
  CHECK_EQ(curr_features.size(), 1) << "Only appearance supported by default "
                                    << "DenseSegmentation.";

  const cv::Mat& input_frame = curr_features[0];
  switch (options_.color_distance) {
    case DenseSegmentationOptions::COLOR_DISTANCE_L2: {
      SpatialCvMatDistance3L2 color_distance(input_frame);
      AddFrameToSegmentation(color_distance, constrained_segmentation);
      break;
    }

    case DenseSegmentationOptions::COLOR_DISTANCE_L1: {
      SpatialCvMatDistance3L1 color_distance(input_frame);
      AddFrameToSegmentation(color_distance, constrained_segmentation);
      break;
    }
  }
}
Exemplo n.º 4
0
static int best_match(uint32_t a) {
	int best_distance = INT32_MAX;
	int best_index = 0;
	for (int j = 0; j < 16; ++j) {
		if (is_gray(a) && !is_gray(vga_base_colors[j]));
		int distance = color_distance(a, vga_base_colors[j]);
		if (distance < best_distance) {
			best_index = j;
			best_distance = distance;
		}
	}
	return best_index;
}
Exemplo n.º 5
0
int QgsDxfExport::closestColorMatch( QRgb pixel )
{
  int idx = 0;
  int current_distance = INT_MAX;
  for ( int i = 1; i < 256; ++i )
  {
    int dist = color_distance( pixel, i );
    if ( dist < current_distance )
    {
      current_distance = dist;
      idx = i;
    }
  }
  return idx;
}
Exemplo n.º 6
0
/* Locates the nearest terminal color. */
static inline unsigned char
get_color(color_T color, struct rgb *palette, int level)
{
	static struct rgb_cache_entry cache[RGB_HASH_SIZE];
	struct rgb_cache_entry *rgb_cache = &cache[HASH_RGB(color, level)];

	/* Uninitialized cache entries have level set to zero. */
	if (rgb_cache->level == 0
	    || rgb_cache->level != level
	    || rgb_cache->rgb != color) {
		struct rgb rgb = INIT_RGB(color);
		unsigned char nearest_color = 0;
		int min_dist = color_distance(&rgb, &palette[0]);
		int i;

#ifdef CONFIG_DEBUG
		if (level <= 0)
			INTERNAL("get_color() called with @level <= 0");
#endif

		for (i = 1; i < level; i++) {
			int dist = color_distance(&rgb, &palette[i]);

			if (dist < min_dist) {
				min_dist = dist;
				nearest_color = i;
			}
		}

		rgb_cache->color = nearest_color;
		rgb_cache->level = level;
		rgb_cache->rgb = color;
	}

	return rgb_cache->color;
}
Exemplo n.º 7
0
void alphaselect2_apply( VJFrame *frame,int tola, int r, int g,
		   int b, int tolb,int alpha)
{
    unsigned int pos;
	const int len = frame->len;
	uint8_t *Y = frame->data[0];
	uint8_t *Cb = frame->data[1];
	uint8_t *Cr = frame->data[2];
	uint8_t *A  = frame->data[3];
	int iy=0,iu=128,iv=128;
	_rgb2yuv(r,g,b,iy,iu,iv);

	const double dtola = tola * 0.1f;
	const double dtolb = tolb * 0.1f;

	if(alpha == 0 ) {
		for (pos = len; pos != 0; pos--) {
			double d = color_distance( Cb[pos],Cr[pos],iu,iv,dtola,dtolb );
			uint8_t av = (uint8_t) (d * 255.0);
			if( av < 0xff ) {
				Cb[pos] = 128;
				Cr[pos] = 128;
			}
			else if (av == 0) {
				Cb[pos] = 128;
				Cr[pos] = 128;
				Y[pos] = pixel_Y_lo_;
			}
			A[pos] = av;
		}
		return;
	}
	
	switch(alpha)
	{
		case 1:
			for (pos = len; pos != 0; pos--) {
				double d = color_distance( Cb[pos],Cr[pos],iu,iv,dtola,dtolb );
				A[pos] = (uint8_t) (d * 255.0);
				if( A[pos] < 0xff ) {
					Y[pos] = A[pos];
					Cb[pos] = 128;
					Cr[pos] = 128;
				}
				else if( A[pos] == 0) {
					Cb[pos] = 128;
					Cr[pos] = 128;
					Y[pos] = pixel_Y_lo_;
				}
			}
			break;
		case 2:
			for (pos = len; pos != 0; pos--) {
				if(A[pos] == 0 )
					continue;
				if(A[pos] == 0xff) {
					Y[pos] = 0xff;
					Cb[pos] = 128;
					Cr[pos] = 128;
				}
				else {
					double d = color_distance( Cb[pos],Cr[pos],iu,iv,dtola,dtolb );
					A[pos] = (uint8_t) (d * 255.0);
					if( A[pos] < 0xff ) {
						Y[pos] = A[pos];
						Cb[pos] = 128;
						Cr[pos] = 128;
					}
					else if( A[pos] == 0) {
						Cb[pos] = 128;
						Cr[pos] = 128;
						Y[pos] = pixel_Y_lo_;
					}
				}
			}
			break;

	}
}
Exemplo n.º 8
0
int MeanShift(const IplImage* img, int **labels)
{
	DECLARE_TIMING(timer);
	START_TIMING(timer);

	int level = 1;
	double color_radius2 = color_radius*color_radius;
	int minRegion = 50;

	// use Lab rather than L*u*v!
	// since Luv may produce noise points
	IplImage *result = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
	cvCvtColor(img, result, CV_RGB2Lab);

	// Step One. Filtering stage of meanshift segmentation
	// http://rsbweb.nih.gov/ij/plugins/download/Mean_Shift.java
	for (int i = 0; i<img->height; i++)
	for (int j = 0; j<img->width; j++)
	{
		int ic = i;
		int jc = j;
		int icOld, jcOld;
		float LOld, UOld, VOld;
		float L = (float)((uchar *)(result->imageData + i*img->widthStep))[j*result->nChannels + 0];
		float U = (float)((uchar *)(result->imageData + i*img->widthStep))[j*result->nChannels + 1];
		float V = (float)((uchar *)(result->imageData + i*img->widthStep))[j*result->nChannels + 2];
		// in the case of 8-bit and 16-bit images R, G and B are converted to floating-point format and scaled to fit 0 to 1 range
		// http://opencv.willowgarage.com/documentation/c/miscellaneous_image_transformations.html
		L = L * 100 / 255;
		U = U - 128;
		V = V - 128;
		double shift = 5;
		for (int iters = 0; shift > 3 && iters < 100; iters++)
		{
			icOld = ic;
			jcOld = jc;
			LOld = L;
			UOld = U;
			VOld = V;

			float mi = 0;
			float mj = 0;
			float mL = 0;
			float mU = 0;
			float mV = 0;
			int num = 0;

			int i2from = max(0, i - spatial_radius), i2to = min(img->height, i + spatial_radius + 1);
			int j2from = max(0, j - spatial_radius), j2to = min(img->width, j + spatial_radius + 1);
			for (int i2 = i2from; i2 < i2to; i2++) {
				for (int j2 = j2from; j2 < j2to; j2++) {
					float L2 = (float)((uchar *)(result->imageData + i2*img->widthStep))[j2*result->nChannels + 0],
						U2 = (float)((uchar *)(result->imageData + i2*img->widthStep))[j2*result->nChannels + 1],
						V2 = (float)((uchar *)(result->imageData + i2*img->widthStep))[j2*result->nChannels + 2];
					L2 = L2 * 100 / 255;
					U2 = U2 - 128;
					V2 = V2 - 128;

					double dL = L2 - L;
					double dU = U2 - U;
					double dV = V2 - V;
					if (dL*dL + dU*dU + dV*dV <= color_radius2) {
						mi += i2;
						mj += j2;
						mL += L2;
						mU += U2;
						mV += V2;
						num++;
					}
				}
			}
			float num_ = 1.f / num;
			L = mL*num_;
			U = mU*num_;
			V = mV*num_;
			ic = (int)(mi*num_ + 0.5);
			jc = (int)(mj*num_ + 0.5);
			int di = ic - icOld;
			int dj = jc - jcOld;
			double dL = L - LOld;
			double dU = U - UOld;
			double dV = V - VOld;

			shift = di*di + dj*dj + dL*dL + dU*dU + dV*dV;
		}

		L = L * 255 / 100;
		U = U + 128;
		V = V + 128;
		((uchar *)(result->imageData + i*img->widthStep))[j*result->nChannels + 0] = (uchar)L;
		((uchar *)(result->imageData + i*img->widthStep))[j*result->nChannels + 1] = (uchar)U;
		((uchar *)(result->imageData + i*img->widthStep))[j*result->nChannels + 2] = (uchar)V;
	}

	IplImage *tobeshow = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);
	cvCvtColor(result, tobeshow, CV_Lab2RGB);
	cvSaveImage("filtered.png", tobeshow);
	cvReleaseImage(&tobeshow);

	// Step Two. Cluster
	// Connect
	int regionCount = 0;
	int *modePointCounts = new int[img->height*img->width];
	memset(modePointCounts, 0, img->width*img->height*sizeof(int));
	float *mode = new float[img->height*img->width * 3];
	{
		int label = -1;
		for (int i = 0; i<img->height; i++)
		for (int j = 0; j<img->width; j++)
			labels[i][j] = -1;
		for (int i = 0; i<img->height; i++)
		for (int j = 0; j<img->width; j++)
		if (labels[i][j]<0)
		{
			labels[i][j] = ++label;
			float L = (float)((uchar *)(result->imageData + i*img->widthStep))[j*result->nChannels + 0],
				U = (float)((uchar *)(result->imageData + i*img->widthStep))[j*result->nChannels + 1],
				V = (float)((uchar *)(result->imageData + i*img->widthStep))[j*result->nChannels + 2];
			mode[label * 3 + 0] = L * 100 / 255;
			mode[label * 3 + 1] = 354 * U / 255 - 134;
			mode[label * 3 + 2] = 256 * V / 255 - 140;
			// Fill
			std::stack<CvPoint> neighStack;
			neighStack.push(cvPoint(i, j));
			const int dxdy[][2] = { { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, -1 }, { 0, 1 }, { 1, -1 }, { 1, 0 }, { 1, 1 } };
			while (!neighStack.empty())
			{
				CvPoint p = neighStack.top();
				neighStack.pop();
				for (int k = 0; k<8; k++)
				{
					int i2 = p.x + dxdy[k][0], j2 = p.y + dxdy[k][1];
					if (i2 >= 0 && j2 >= 0 && i2<img->height && j2<img->width && labels[i2][j2]<0 && color_distance(result, i, j, i2, j2)<color_radius2)
					{
						labels[i2][j2] = label;
						neighStack.push(cvPoint(i2, j2));
						modePointCounts[label]++;
						L = (float)((uchar *)(result->imageData + i2*img->widthStep))[j2*result->nChannels + 0];
						U = (float)((uchar *)(result->imageData + i2*img->widthStep))[j2*result->nChannels + 1];
						V = (float)((uchar *)(result->imageData + i2*img->widthStep))[j2*result->nChannels + 2];
						mode[label * 3 + 0] += L * 100 / 255;
						mode[label * 3 + 1] += 354 * U / 255 - 134;
						mode[label * 3 + 2] += 256 * V / 255 - 140;
					}
				}
			}
			mode[label * 3 + 0] /= modePointCounts[label];
			mode[label * 3 + 1] /= modePointCounts[label];
			mode[label * 3 + 2] /= modePointCounts[label];
		}
		//current Region count
		regionCount = label + 1;
	}
	std::cout << "Mean Shift(Connect):" << regionCount << std::endl;
	int oldRegionCount = regionCount;

	// TransitiveClosure
	for (int counter = 0, deltaRegionCount = 1; counter<5 && deltaRegionCount>0; counter++)
	{
		// 1.Build RAM using classifiction structure
		RAList *raList = new RAList[regionCount], *raPool = new RAList[10 * regionCount];	//10 is hard coded!
		for (int i = 0; i < regionCount; i++)
		{
			raList[i].label = i;
			raList[i].next = NULL;
		}
		for (int i = 0; i < regionCount * 10 - 1; i++)
		{
			raPool[i].next = &raPool[i + 1];
		}
		raPool[10 * regionCount - 1].next = NULL;
		RAList	*raNode1, *raNode2, *oldRAFreeList, *freeRAList = raPool;
		for (int i = 0; i<img->height; i++)
		for (int j = 0; j<img->width; j++)
		{
			if (i>0 && labels[i][j] != labels[i - 1][j])
			{
				// Get 2 free node
				raNode1 = freeRAList;
				raNode2 = freeRAList->next;
				oldRAFreeList = freeRAList;
				freeRAList = freeRAList->next->next;
				// connect the two region
				raNode1->label = labels[i][j];
				raNode2->label = labels[i - 1][j];
				if (raList[labels[i][j]].Insert(raNode2))	//already exists!
					freeRAList = oldRAFreeList;
				else
					raList[labels[i - 1][j]].Insert(raNode1);
			}
			if (j>0 && labels[i][j] != labels[i][j - 1])
			{
				// Get 2 free node
				raNode1 = freeRAList;
				raNode2 = freeRAList->next;
				oldRAFreeList = freeRAList;
				freeRAList = freeRAList->next->next;
				// connect the two region
				raNode1->label = labels[i][j];
				raNode2->label = labels[i][j - 1];
				if (raList[labels[i][j]].Insert(raNode2))
					freeRAList = oldRAFreeList;
				else
					raList[labels[i][j - 1]].Insert(raNode1);
			}
		}

		// 2.Treat each region Ri as a disjoint set
		for (int i = 0; i < regionCount; i++)
		{
			RAList	*neighbor = raList[i].next;
			while (neighbor)
			{
				if (color_distance(&mode[3 * i], &mode[3 * neighbor->label])<color_radius2)
				{
					int iCanEl = i, neighCanEl = neighbor->label;
					while (raList[iCanEl].label != iCanEl) iCanEl = raList[iCanEl].label;
					while (raList[neighCanEl].label != neighCanEl) neighCanEl = raList[neighCanEl].label;
					if (iCanEl<neighCanEl)
						raList[neighCanEl].label = iCanEl;
					else
					{
						//raList[raList[iCanEl].label].label = iCanEl;
						raList[iCanEl].label = neighCanEl;
					}
				}
				neighbor = neighbor->next;
			}
		}
		// 3. Union Find
		for (int i = 0; i < regionCount; i++)
		{
			int iCanEl = i;
			while (raList[iCanEl].label != iCanEl) iCanEl = raList[iCanEl].label;
			raList[i].label = iCanEl;
		}
		// 4. Traverse joint sets, relabeling image.
		int *modePointCounts_buffer = new int[regionCount];
		memset(modePointCounts_buffer, 0, regionCount*sizeof(int));
		float *mode_buffer = new float[regionCount * 3];
		int	*label_buffer = new int[regionCount];

		for (int i = 0; i<regionCount; i++)
		{
			label_buffer[i] = -1;
			mode_buffer[i * 3 + 0] = 0;
			mode_buffer[i * 3 + 1] = 0;
			mode_buffer[i * 3 + 2] = 0;
		}
		for (int i = 0; i<regionCount; i++)
		{
			int iCanEl = raList[i].label;
			modePointCounts_buffer[iCanEl] += modePointCounts[i];
			for (int k = 0; k<3; k++)
				mode_buffer[iCanEl * 3 + k] += mode[i * 3 + k] * modePointCounts[i];
		}
		int	label = -1;
		for (int i = 0; i < regionCount; i++)
		{
			int iCanEl = raList[i].label;
			if (label_buffer[iCanEl] < 0)
			{
				label_buffer[iCanEl] = ++label;

				for (int k = 0; k < 3; k++)
					mode[label * 3 + k] = (mode_buffer[iCanEl * 3 + k]) / (modePointCounts_buffer[iCanEl]);

				modePointCounts[label] = modePointCounts_buffer[iCanEl];
			}
		}
		regionCount = label + 1;
		for (int i = 0; i < img->height; i++)
		for (int j = 0; j < img->width; j++)
			labels[i][j] = label_buffer[raList[labels[i][j]].label];

		delete[] mode_buffer;
		delete[] modePointCounts_buffer;
		delete[] label_buffer;

		//Destroy RAM
		delete[] raList;
		delete[] raPool;

		deltaRegionCount = oldRegionCount - regionCount;
		oldRegionCount = regionCount;
		std::cout << "Mean Shift(TransitiveClosure):" << regionCount << std::endl;
	}

	// Prune
	{
		int *modePointCounts_buffer = new int[regionCount];
		float *mode_buffer = new float[regionCount * 3];
		int	*label_buffer = new int[regionCount];
		int minRegionCount;

		do{
			minRegionCount = 0;
			// Build RAM again
			RAList *raList = new RAList[regionCount], *raPool = new RAList[10 * regionCount];	//10 is hard coded!
			for (int i = 0; i < regionCount; i++)
			{
				raList[i].label = i;
				raList[i].next = NULL;
			}
			for (int i = 0; i < regionCount * 10 - 1; i++)
			{
				raPool[i].next = &raPool[i + 1];
			}
			raPool[10 * regionCount - 1].next = NULL;
			RAList	*raNode1, *raNode2, *oldRAFreeList, *freeRAList = raPool;
			for (int i = 0; i<img->height; i++)
			for (int j = 0; j<img->width; j++)
			{
				if (i>0 && labels[i][j] != labels[i - 1][j])
				{
					// Get 2 free node
					raNode1 = freeRAList;
					raNode2 = freeRAList->next;
					oldRAFreeList = freeRAList;
					freeRAList = freeRAList->next->next;
					// connect the two region
					raNode1->label = labels[i][j];
					raNode2->label = labels[i - 1][j];
					if (raList[labels[i][j]].Insert(raNode2))	//already exists!
						freeRAList = oldRAFreeList;
					else
						raList[labels[i - 1][j]].Insert(raNode1);
				}
				if (j>0 && labels[i][j] != labels[i][j - 1])
				{
					// Get 2 free node
					raNode1 = freeRAList;
					raNode2 = freeRAList->next;
					oldRAFreeList = freeRAList;
					freeRAList = freeRAList->next->next;
					// connect the two region
					raNode1->label = labels[i][j];
					raNode2->label = labels[i][j - 1];
					if (raList[labels[i][j]].Insert(raNode2))
						freeRAList = oldRAFreeList;
					else
						raList[labels[i][j - 1]].Insert(raNode1);
				}
			}
			// Find small regions
			for (int i = 0; i < regionCount; i++)
			if (modePointCounts[i] < minRegion)
			{
				minRegionCount++;
				RAList *neighbor = raList[i].next;
				int candidate = neighbor->label;
				float minDistance = color_distance(&mode[3 * i], &mode[3 * candidate]);
				neighbor = neighbor->next;
				while (neighbor)
				{
					float minDistance2 = color_distance(&mode[3 * i], &mode[3 * neighbor->label]);
					if (minDistance2<minDistance)
					{
						minDistance = minDistance2;
						candidate = neighbor->label;
					}
					neighbor = neighbor->next;
				}
				int iCanEl = i, neighCanEl = candidate;
				while (raList[iCanEl].label != iCanEl) iCanEl = raList[iCanEl].label;
				while (raList[neighCanEl].label != neighCanEl) neighCanEl = raList[neighCanEl].label;
				if (iCanEl < neighCanEl)
					raList[neighCanEl].label = iCanEl;
				else
				{
					//raList[raList[iCanEl].label].label	= neighCanEl;
					raList[iCanEl].label = neighCanEl;
				}
			}
			for (int i = 0; i < regionCount; i++)
			{
				int iCanEl = i;
				while (raList[iCanEl].label != iCanEl)
					iCanEl = raList[iCanEl].label;
				raList[i].label = iCanEl;
			}
			memset(modePointCounts_buffer, 0, regionCount*sizeof(int));
			for (int i = 0; i < regionCount; i++)
			{
				label_buffer[i] = -1;
				mode_buffer[3 * i + 0] = 0;
				mode_buffer[3 * i + 1] = 0;
				mode_buffer[3 * i + 2] = 0;
			}
			for (int i = 0; i<regionCount; i++)
			{
				int iCanEl = raList[i].label;
				modePointCounts_buffer[iCanEl] += modePointCounts[i];
				for (int k = 0; k<3; k++)
					mode_buffer[iCanEl * 3 + k] += mode[i * 3 + k] * modePointCounts[i];
			}
			int	label = -1;
			for (int i = 0; i < regionCount; i++)
			{
				int iCanEl = raList[i].label;
				if (label_buffer[iCanEl] < 0)
				{
					label_buffer[iCanEl] = ++label;

					for (int k = 0; k < 3; k++)
						mode[label * 3 + k] = (mode_buffer[iCanEl * 3 + k]) / (modePointCounts_buffer[iCanEl]);

					modePointCounts[label] = modePointCounts_buffer[iCanEl];
				}
			}
			regionCount = label + 1;
			for (int i = 0; i < img->height; i++)
			for (int j = 0; j < img->width; j++)
				labels[i][j] = label_buffer[raList[labels[i][j]].label];
			//Destroy RAM
			delete[] raList;
			delete[] raPool;
			std::cout << "Mean Shift(Prune):" << regionCount << std::endl;
		} while (minRegionCount > 0);

		delete[] mode_buffer;
		delete[] modePointCounts_buffer;
		delete[] label_buffer;
	}

	// Output
	STOP_TIMING(timer);
	std::cout << "Mean Shift(ms):" << GET_TIMING(timer) << std::endl;

	cvReleaseImage(&result);
	delete[]mode;
	delete[]modePointCounts;
	return regionCount;
}