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

📄 yuvmedianfilter.c

📁 Motion JPEG编解码器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *    Copyright (C) 2001 Mike Bernson <mike@mlb.org> * *    This program is free software; you can redistribute it and/or modify *    it under the terms of the GNU General Public License as published by *    the Free Software Foundation; either version 2 of the License, or *    (at your option) any later version. * *    This program is distributed in the hope that it will be useful, *    but WITHOUT ANY WARRANTY; without even the implied warranty of *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *    GNU General Public License for more details. * *    You should have received a copy of the GNU General Public License *    along with this program; if not, write to the Free Software *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * *    Filter Based on code from Jim Cassburi filter: 2dclean * *    This filter look around the current point for a radius and averages *    this values that fall inside a threshold. */#include <config.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include "yuv4mpeg.h"#include "mjpeg_logging.h"int verbose = 1;uint8_t	*input_frame[3];uint8_t	*output_frame[3];void	filter(int width, int height, uint8_t *const input[], uint8_t *output[]);void	filter_buffer(int width, int height, int stride, int radius, int threshold, uint8_t * const input, uint8_t * const output);void	filter_buffer_fast(int width, int height, int stride, int radius, int threshold, uint8_t * const input, uint8_t * const output);int	threshold_luma = 2;int	threshold_chroma = 2;int	radius_luma = 2;int	radius_chroma = 2;int	interlace = -1;int param_skip = 0;int param_fast = 0;int param_weight_type = 0;	/* 0 = use param_weight, 1 = 8, 2 = 2.667,							   3 = 13.333, 4 = 24 */double param_weight = 8.0;#define	NUMAVG	1024int	avg_replace[NUMAVG];int	chroma_mode;int     SS_H = 2;int     SS_V = 2;static void Usage(char *name ){	fprintf(stderr,		"Usage: %s: [-h] [-r num] [-R num] [-t num] [-T num] [-v num]\n"                "-h   - Print out this help\n"		"-r   - Radius for luma median (default: 2 pixels)\n"		"-R   - Radius for chroma median (default: 2 pixels)\n"		"-t   - Trigger luma threshold (default: 2 [0=disable])\n"		"-T   - Trigger chroma threshold (default: 2 [0=disable])\n"		"-I   - Interlacing 0=off 1=on (default: taken from yuv stream)\n"		"-f   - Fast mode (i.e. no trigger threshold, just simple mean)\n"		"-w   - Weight given to current pixel vs. pixel in radius (default: 8)\n"		"-v   - Verbosity [0..2]\n", name);}			intmain(int argc, char *argv[]){	int	i;	long long avg;	int	input_fd = 0;	int	output_fd = 1;	int	horz;	int	vert;	int	c;	int	frame_count;	y4m_stream_info_t istream, ostream;	y4m_frame_info_t iframe;	y4m_accept_extensions(1);	while((c = getopt(argc, argv, "r:R:t:T:v:S:hI:w:f")) != EOF) {		switch(c) {		case 'r':			radius_luma = atoi(optarg);			break;		case 'R':			radius_chroma = atoi(optarg);			break;		case 't':			threshold_luma = atoi(optarg);			break;		case 'T':			threshold_chroma = atoi(optarg);			break;		case 'I':			interlace = atoi (optarg);			if (interlace != 0 && interlace != 1)			{				Usage (argv[0]);				exit (1);			}			break;		case 'S':			param_skip = atoi (optarg);			break;		case 'f':			param_fast = 1;			break;		case 'w':			if (strcmp (optarg, "8") == 0)				param_weight_type = 1;			else if (strcmp (optarg, "2.667") == 0)				param_weight_type = 2;			else if (strcmp (optarg, "13.333") == 0)				param_weight_type = 3;			else if (strcmp (optarg, "24") == 0)				param_weight_type = 4;			else				param_weight_type = 0;			param_weight = atof (optarg);			break;		case 'v':			verbose = atoi (optarg);			if (verbose < 0 || verbose >2)			{				Usage (argv[0]);				exit (1);			}			break;		  					case 'h':                        Usage (argv[0]);		default:			exit(0);		}	}	mjpeg_info ("fast %d, weight type %d\n", param_fast,		param_weight_type);	if (radius_luma <= 0 || radius_chroma <= 0)	   mjpeg_error_exit1("radius values must be > 0!");	if (threshold_luma < 0 || threshold_chroma < 0)	   mjpeg_error_exit1("threshold values must be >= 0!");   (void)mjpeg_default_handler_verbosity(verbose);	y4m_init_stream_info(&istream);	y4m_init_stream_info(&ostream);	y4m_init_frame_info(&iframe);	i = y4m_read_stream_header(input_fd, &istream);	if (i != Y4M_OK)	  mjpeg_error_exit1("Input stream error: %s", y4m_strerr(i));	if (y4m_si_get_plane_count(&istream) != 3)	   mjpeg_error_exit1("Only 3 plane formats supported");	chroma_mode = y4m_si_get_chroma(&istream);	SS_H = y4m_chroma_ss_x_ratio(chroma_mode).d;	SS_V = y4m_chroma_ss_y_ratio(chroma_mode).d;	mjpeg_debug("chroma subsampling: %dH %dV\n",SS_H,SS_V);	if (interlace == -1)	{	  i = y4m_si_get_interlace(&istream);	  switch (i)	  {	  case Y4M_ILACE_NONE:	       interlace = 0;	       break;	  case Y4M_ILACE_BOTTOM_FIRST:	  case Y4M_ILACE_TOP_FIRST:	       interlace = 1;	       break;	  default:	       mjpeg_warn("Unknown interlacing '%d', assuming non-interlaced", i);	       interlace = 0;	       break;	  }	}	if( interlace && y4m_si_get_height(&istream) % 2 != 0 )		mjpeg_error_exit1("Input images have odd number of lines - can't treats as interlaced!" );	horz = y4m_si_get_width(&istream);	vert = y4m_si_get_height(&istream);	mjpeg_debug("width=%d height=%d luma_r=%d chroma_r=%d luma_t=%d chroma_t=%d", horz, vert, radius_luma, radius_chroma, threshold_luma, threshold_chroma);	y4m_copy_stream_info(&ostream, &istream);	input_frame[0] = malloc(horz * vert);	input_frame[1] = malloc((horz / SS_H) * (vert / SS_V));	input_frame[2] = malloc((horz / SS_H) * (vert / SS_V));	output_frame[0] = malloc(horz * vert);	output_frame[1] = malloc((horz / SS_H) * (vert / SS_V));	output_frame[2] = malloc((horz / SS_H) * (vert / SS_V));	y4m_write_stream_header(output_fd, &ostream);	frame_count = 0;	while (y4m_read_frame(input_fd, &istream, &iframe, input_frame) == Y4M_OK)	{ 		frame_count++;		if (frame_count > param_skip)		{		  filter(horz, vert,  input_frame, output_frame);		  y4m_write_frame(output_fd, &ostream, &iframe, output_frame);		}		else		  y4m_write_frame(output_fd, &ostream, &iframe, input_frame);	}	for (avg=0, i=0; i < NUMAVG; i++)		avg += avg_replace[i];	mjpeg_info("frames=%d avg=%lld", frame_count, avg);	for (i=0; i < NUMAVG; i++) {		mjpeg_debug( "%02d: %6.2f", i,			(((double)avg_replace[i]) * 100.0)/(double)(avg));	}	y4m_fini_stream_info(&istream);	y4m_fini_stream_info(&ostream);	y4m_fini_frame_info(&iframe);	exit(0);}voidfilter(int width, int height, uint8_t * const input[], uint8_t *output[]){	if (param_fast)	{		if( interlace )		{			filter_buffer_fast(width, height/2, width*2, 						  radius_luma, threshold_luma, 						  input[0], output[0]);			filter_buffer_fast(width, height/2, width*2, 						  radius_luma, threshold_luma, 						  input[0]+width, output[0]+width);				filter_buffer_fast(width/SS_H, (height/SS_V)/2, (width/SS_H)*2, 						  radius_chroma, threshold_chroma, 						  input[1], output[1]);			filter_buffer_fast(width/SS_H, (height/SS_V)/2, (width/SS_H)*2, 						  radius_chroma, threshold_chroma, 						  input[1]+width/SS_H, output[1]+width/SS_H);				filter_buffer_fast(width/SS_H, (height/SS_V)/2, (width/SS_H)*2, 						  radius_chroma, threshold_chroma, 						  input[2], output[2]);			filter_buffer_fast(width/SS_H, (height/SS_V)/2, (width/SS_H)*2,						  radius_chroma, threshold_chroma, 						  input[2]+width/SS_H, output[2]+width/SS_H);		}		else		{			filter_buffer_fast(width, height, width, 							  radius_luma, threshold_luma, 							  input[0], output[0]);			filter_buffer_fast(width/SS_H, height/SS_V, width/SS_H, 						  radius_chroma, threshold_chroma, 						  input[1], output[1]);			filter_buffer_fast(width/SS_H, height/SS_V, width/SS_H, 						  radius_chroma, threshold_chroma, 						  input[2], output[2]);		}	}	else	{		if( interlace )		{			filter_buffer(width, height/2, width*2, 						  radius_luma, threshold_luma, 						  input[0], output[0]);			filter_buffer(width, height/2, width*2, 						  radius_luma, threshold_luma, 						  input[0]+width, output[0]+width);				filter_buffer(width/SS_H, (height/SS_V)/2, (width/SS_H)*2, 						  radius_chroma, threshold_chroma, 						  input[1], output[1]);			filter_buffer(width/SS_H, (height/SS_V)/2, (width/SS_H)*2, 						  radius_chroma, threshold_chroma, 						  input[1]+width/SS_H, output[1]+width/SS_H);				filter_buffer(width/SS_H, (height/SS_V)/2, (width/SS_H)*2, 						  radius_chroma, threshold_chroma, 						  input[2], output[2]);			filter_buffer(width/SS_H, (height/SS_V)/2, (width/SS_H)*2,						  radius_chroma, threshold_chroma, 						  input[2]+width/SS_H, output[2]+width/SS_H);		}		else		{			filter_buffer(width, height, width, 							  radius_luma, threshold_luma, 							  input[0], output[0]);			filter_buffer(width/SS_H, height/SS_V, width/SS_H, 						  radius_chroma, threshold_chroma, 						  input[1], output[1]);			filter_buffer(width/SS_H, height/SS_V, width/SS_H, 						  radius_chroma, threshold_chroma, 						  input[2], output[2]);		}	}}voidfilter_buffer(int width, int height, int row_stride,			  int radius, int threshold, uint8_t * const input, uint8_t * const output){	int	reference;	int	diff;	int	a;	int	b;	uint8_t *pixel;	int	total;	int	count;	int	radius_count;	int	x;	int	y;	int	offset;	int	min_count;	uint8_t *inpix, *refpix;	uint8_t *outpix;	radius_count = radius + radius + 1;	min_count = (radius_count * radius_count + 2)/3;		if (threshold == 0)	   {           for (y = 0; y < height; y++)	       memcpy(&output[y * row_stride], &input[y * row_stride], width);	   return;           }	for(y=0; y < radius; y++)		memcpy(&output[y * row_stride], &input[y * row_stride], width);	for(y=height - radius; y < height; y++)

⌨️ 快捷键说明

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