⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alg.c

📁 motion motion
💻 C
📖 第 1 页 / 共 3 页
字号:
					labelsize=iflood(ix, iy, width, height, out, labels, current_label+32768, current_label);					imgs->labelgroup_max+=labelsize;					imgs->labels_above++;				}								if( imgs->labelsize_max < labelsize ){					imgs->labelsize_max=labelsize;					imgs->largest_label=current_label;				}								cnt->current_image->total_labels++;				current_label++;			}		}		pixelpos++; /* compensate for ix<width-1 */	}		//printf( "%i Labels found. Largest connected Area: %i Pixel(s). Largest Label: %i\n", imgs->total_labels, imgs->labelsize_max, cnt->current_image->largest_label);	/* return group of significant labels */	return imgs->labelgroup_max;}/* Dilates a 3x3 box */static int dilate9(unsigned char *img, int width, int height, void *buffer){	/* - row1, row2 and row3 represent lines in the temporary buffer 	 * - window is a sliding window containing max values of the columns	 *   in the 3x3 matrix	 * - widx is an index into the sliding window (this is faster than 	 *   doing modulo 3 on i)	 * - blob keeps the current max value	 */	int y, i, sum = 0, widx;	unsigned char *row1, *row2, *row3, *rowTemp,*yp;	unsigned char window[3], blob, latest;	/* Set up row pointers in the temporary buffer. */	row1 = buffer;	row2 = row1 + width;	row3 = row2 + width;	/* Init rows 2 and 3. */	memset(row2, 0, width);	memcpy(row3, img, width);	/* Pointer to the current row in img. */	yp = img;		for (y = 0; y < height; y++) {		/* Move down one step; row 1 becomes the previous row 2 and so on. */		rowTemp = row1;		row1 = row2;		row2 = row3;		row3 = rowTemp;		/* If we're at the last row, fill with zeros, otherwise copy from img. */		if(y == height - 1)			memset(row3, 0, width);		else			memcpy(row3, yp+width, width);				/* Init slots 0 and 1 in the moving window. */		window[0] = MAX3(row1[0], row2[0], row3[0]);		window[1] = MAX3(row1[1], row2[1], row3[1]);		/* Init blob to the current max, and set window index. */		blob = MAX2(window[0], window[1]);		widx = 2;		/* Iterate over the current row; index i is off by one to eliminate		 * a lot of +1es in the loop.		 */		for (i = 2; i <= width - 1; i++) {			/* Get the max value of the next column in the 3x3 matrix. */			latest = window[widx] = MAX3(row1[i], row2[i], row3[i]);			/* If the value is larger than the current max, use it. Otherwise,			 * calculate a new max (because the new value may not be the max.			 */			if(latest >= blob)				blob = latest;			else				blob = MAX3(window[0], window[1], window[2]);			/* Write the max value (blob) to the image. */			if (blob != 0) {				*(yp + i - 1) = blob;				sum++;			}			/* Wrap around the window index if necessary. */			if(++widx == 3)				widx = 0;		}		/* Store zeros in the vertical sides. */		*yp = *(yp + width - 1) = 0;		yp += width;	}		return sum;}/* Dilates a + shape */static int dilate5(unsigned char *img, int width, int height, void *buffer){	/* - row1, row2 and row3 represent lines in the temporary buffer 	 * - mem holds the max value of the overlapping part of two + shapes	 */	int y, i, sum = 0;	unsigned char *row1, *row2, *row3, *rowTemp, *yp;	unsigned char blob, mem, latest;		/* Set up row pointers in the temporary buffer. */	row1 = buffer;	row2 = row1 + width;	row3 = row2 + width;		/* Init rows 2 and 3. */	memset(row2, 0, width);	memcpy(row3, img, width);		/* Pointer to the current row in img. */	yp = img;	for (y = 0; y < height; y++) {		/* Move down one step; row 1 becomes the previous row 2 and so on. */		rowTemp = row1;		row1 = row2;		row2 = row3;		row3 = rowTemp;				/* If we're at the last row, fill with zeros, otherwise copy from img. */		if (y == height - 1)			memset(row3, 0, width);		else			memcpy(row3, yp+width, width);		/* Init mem and set blob to force an evaluation of the entire + shape. */		mem = MAX2(row2[0], row2[1]);		blob = 1; /* dummy value, must be > 0 */				for (i = 1; i < width - 1; i++) {			/* Get the max value of the "right edge" of the + shape. */			latest = MAX3(row1[i], row2[i + 1], row3[i]);						if (blob == 0) {				/* In case the last blob is zero, only latest matters. */				blob = latest;				mem = row2[i + 1];			} else {				/* Otherwise, we have to check both latest and mem. */				blob = MAX2(mem, latest);				mem = MAX2(row2[i], row2[i+1]);			}			/* Write the max value (blob) to the image. */			if (blob != 0) {				*(yp + i) = blob;				sum++;			}		}		/* Store zeros in the vertical sides. */		*yp = *(yp + width - 1) = 0;		yp += width;	}	return sum;}/* Erodes a 3x3 box */static int erode9(unsigned char *img, int width, int height, void *buffer, unsigned char flag){	int y, i, sum = 0;	char *Row1,*Row2,*Row3;	Row1 = buffer;	Row2 = Row1 + width;	Row3 = Row1 + 2*width;	memset(Row2, flag, width);	memcpy(Row3, img, width);	for (y = 0; y < height; y++) {		memcpy(Row1, Row2, width);		memcpy(Row2, Row3, width);		if (y == height-1)			memset(Row3, flag, width);		else			memcpy(Row3, img+(y+1)*width, width);		for (i = width-2; i >= 1; i--) {			if (Row1[i-1] == 0 ||				Row1[i]   == 0 ||				Row1[i+1] == 0 ||				Row2[i-1] == 0 ||				Row2[i]   == 0 ||				Row2[i+1] == 0 ||				Row3[i-1] == 0 ||				Row3[i]   == 0 ||				Row3[i+1] == 0)				img[y*width+i] = 0;			else				sum++;		}		img[y*width] = img[y*width+width-1] = flag;	}	return sum;}/* Erodes in a + shape */static int erode5(unsigned char *img, int width, int height, void *buffer, unsigned char flag){	int y, i, sum = 0;	char *Row1,*Row2,*Row3;	Row1 = buffer;	Row2 = Row1 + width;	Row3 = Row1 + 2*width;	memset(Row2, flag, width);	memcpy(Row3, img, width);	for (y = 0; y < height; y++) {		memcpy(Row1, Row2, width);		memcpy(Row2, Row3, width);		if (y == height-1)			memset(Row3, flag, width);		else			memcpy(Row3, img+(y+1)*width, width);		for (i = width-2; i >= 1; i--) {			if (Row1[i]   == 0 ||				Row2[i-1] == 0 ||				Row2[i]   == 0 ||				Row2[i+1] == 0 ||				Row3[i]   == 0)				img[y*width+i] = 0;			else				sum++;		}		img[y*width] = img[y*width+width-1] = flag;	}	return sum;}/*  * Despeckling routine to remove noisy detections. */int alg_despeckle(struct context *cnt, int olddiffs){	int diffs = 0;	unsigned char *out = cnt->imgs.out;	int width = cnt->imgs.width;	int height= cnt->imgs.height;	int done = 0, i, len = strlen(cnt->conf.despeckle);	unsigned char *common_buffer = cnt->imgs.common_buffer;	for (i = 0; i < len; i++) {		switch (cnt->conf.despeckle[i]) {		case 'E':			if ((diffs = erode9(out, width, height, common_buffer, 0)) == 0) i=len;			done=1;			break;		case 'e':			if ((diffs = erode5(out, width, height, common_buffer, 0)) == 0) i=len;			done=1;			break;		case 'D':			diffs = dilate9(out, width, height, common_buffer);			done=1;			break;		case 'd':			diffs = dilate5(out, width, height, common_buffer);			done=1;			break;		/* no further despeckle after labeling! */		case 'l':			diffs = alg_labeling(cnt);			i=len;			done=2;			break;		}	}	/* If conf.despeckle contains any valid action EeDdl */	if (done){		if (done != 2) cnt->imgs.labelsize_max = 0; // Disable Labeling		return diffs;	}		else		cnt->imgs.labelsize_max = 0; // Disable Labeling		return olddiffs;}/* Generate actual smartmask. Calculate sensitivity based on motion */void alg_tune_smartmask(struct context *cnt){	int i, diff;		int motionsize = cnt->imgs.motionsize;	unsigned char *smartmask = cnt->imgs.smartmask;	unsigned char *smartmask_final = cnt->imgs.smartmask_final;	int *smartmask_buffer = cnt->imgs.smartmask_buffer;	int sensitivity=cnt->lastrate*(11-cnt->smartmask_speed);	for (i=0; i<motionsize; i++)	{		/* Decrease smart_mask sensitivity every 5*speed seconds only */		if (smartmask[i] > 0)			smartmask[i]--;		/* Increase smart_mask sensitivity based on the buffered values */		diff = smartmask_buffer[i]/sensitivity;		if (diff){			if (smartmask[i] <= diff+80)				smartmask[i]+=diff;			else				smartmask[i]=80;			smartmask_buffer[i]%=sensitivity;		}		/* Transfer raw mask to the final stage when above trigger value */		if (smartmask[i]>20)			smartmask_final[i]=0;		else			smartmask_final[i]=255;	}	/* Further expansion (here:erode due to inverted logic!) of the mask */	diff = erode9(smartmask_final, cnt->imgs.width, cnt->imgs.height, cnt->imgs.common_buffer, 255);	diff = erode5(smartmask_final, cnt->imgs.width, cnt->imgs.height, cnt->imgs.common_buffer, 255);}/* Increment for *smartmask_buffer in alg_diff_standard. */#define SMARTMASK_SENSITIVITY_INCR 5int alg_diff_standard (struct context *cnt, unsigned char *new){	struct images *imgs=&cnt->imgs;	int i, diffs=0;	int noise=cnt->noise;	int smartmask_speed=cnt->smartmask_speed;	unsigned char *ref=imgs->ref;	unsigned char *out=imgs->out;	unsigned char *mask=imgs->mask;	unsigned char *smartmask_final=imgs->smartmask_final;	int *smartmask_buffer=imgs->smartmask_buffer;#ifdef HAVE_MMX	mmx_t mmtemp; /* used for transferring to/from memory */	int unload;   /* counter for unloading diff counts */#endif	i=imgs->motionsize;	memset(out+i, 128, i/2); /* motion pictures are now b/w i.o. green */	/* Keeping this memset in the MMX case when zeroes are necessarily 	 * written anyway seems to be beneficial in terms of speed. Perhaps a	 * cache thing?	 */	memset(out, 0, i);#ifdef HAVE_MMX	/* NOTE: The Pentium has two instruction pipes: U and V. I have grouped MMX	 * instructions in pairs according to how I think they will be scheduled in 	 * the U and V pipes. Due to pairing constraints, the V pipe will sometimes	 * be empty (for example, memory access always goes into the U pipe).	 *	 * The following MMX registers are kept throughout the loop:	 * mm5 - 8 separate diff counters (unloaded periodically)	 * mm6 - mask: 00ff 00ff 00ff 00ff	 * mm7 - noise level as 8 packed bytes	 *	 * -- Per Jonsson	 */	/* To avoid a div, we work with differences multiplied by 255 in the	 * default case and *mask otherwise. Thus, the limit to compare with is	 * 255*(noise+1)-1).	 */	mmtemp.uw[0] = mmtemp.uw[1] = mmtemp.uw[2] = mmtemp.uw[3] =		(unsigned short)(noise * 255 + 254);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -