Previous topicNext topic

Removing background of image to use in Magic Module

Questions, comments, feedback, etc.
Post Reply
wellsley
Posts: 8
Joined: Fri Aug 14, 2015 8:38 am

Removing background of image to use in Magic Module

Post by wellsley »

My apologies first as this is from a brand new user, I am stuck with what may be a simple fix, I have an image and I want to just use one part of it, basically removing the background to leave only a specific part of the image, so I can import that specific part of the image into the Magic workspace. Culd anyone help me out with a solution of how to do this, it would be much appreciated
Thanks
Magic
Site Admin
Posts: 3677
Joined: Wed Apr 09, 2014 9:28 pm

Re: Removing background of image to use in Magic Module

Post by Magic »

Hmm, well there are probably several ways to do that, but wouldn't it be easier to just edit the image in Photoshop?
wellsley
Posts: 8
Joined: Fri Aug 14, 2015 8:38 am

Re: Removing background of image to use in Magic Module

Post by wellsley »

Thanks for your reply,
Ive only just recently bought Photoshop Elements, and have yet to get to grips with that as well, so just wondering how other people went about doing this, hopefully I can figure out how to do it. Oh really loving this programe
Magic
Site Admin
Posts: 3677
Joined: Wed Apr 09, 2014 9:28 pm

Re: Removing background of image to use in Magic Module

Post by Magic »

The only reason you should use Magic to remove an image background is if you wanted to animate the removal somehow -- i.e., remove different parts at different times, or remove parts of a video, etc. Have a look at the LayersExamples project (Help > Open Sample Project) to get an idea of what I mean. The first tab, Mask Example, is probably the most relevant.

If you just want to remove the background once and then forget about it, I would definitely recommend Photoshop though.

It's always best to do any image/video preparation outside of Magic when you can, so that when you are actually running Magic, it uses less CPU/GPU resources and therefore maintains as high a frame rate as possible.
bareimage
Posts: 24
Joined: Wed Sep 02, 2015 5:14 am

Re: Removing background of image to use in Magic Module

Post by bareimage »

This is actually interesting question. What is happening in magic, is that it is treating black color as black color. Magic respects alpha chanel of the image source, you can use Layer >MASK to remove the background.... But you need alpha channel data
bareimage
Posts: 24
Joined: Wed Sep 02, 2015 5:14 am

Re: Removing background of image to use in Magic Module

Post by bareimage »

You shout try this:

This will remove the background, but it is pain to setup. Does work...

Code: Select all

/*{
	"CREDIT": "by VIDVOX",
	"CATEGORIES": [
		"Color Effect", "Masking"
	],
	"INPUTS": [
		{
			"NAME": "inputImage",
			"TYPE": "image"
		},
		{
			"LABEL": "Key Color",
			"NAME": "mask_color",
			"TYPE": "color",
			"DEFAULT": [
				0.24,
				0.77,
				0.38,
				1.0
			]
		},
		{
			"LABEL": "Show Alpha",
			"NAME": "showAlpha",
			"TYPE": "bool",
			"DEFAULT": false
		},
		{
			"LABEL": "Hard Cutoff",
			"NAME": "applyCutOff",
			"TYPE": "bool",
			"DEFAULT": false
		},
		{
			"LABEL": "Cutoff Thresh",
			"NAME": "cutoffThresh",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 1.0,
			"DEFAULT": 0.5
		},
		{
			"LABEL": "HUE- Tol.",
			"NAME": "hueTol",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 0.25,
			"DEFAULT": 0.0
		},
		{
			"LABEL": "HUE- Min. Bracket",
			"NAME": "hueMinBracket",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 0.5,
			"DEFAULT": 0.25
		},
		{
			"LABEL": "HUE- Max Bracket",
			"NAME": "hueMaxBracket",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 0.5,
			"DEFAULT": 0.25
		},
		{
			"LABEL": "SAT- Tol.",
			"NAME": "satTol",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 0.5,
			"DEFAULT": 0.0
		},
		{
			"LABEL": "SAT- Min. Bracket",
			"NAME": "satMinBracket",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 1.0,
			"DEFAULT": 0.5
		},
		{
			"LABEL": "SAT- Max Bracket",
			"NAME": "satMaxBracket",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 1.0,
			"DEFAULT": 0.5
		},
		{
			"LABEL": "VAL- Tol.",
			"NAME": "valTol",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 0.5,
			"DEFAULT": 0.0
		},
		{
			"LABEL": "VAL- Min. Bracket",
			"NAME": "valMinBracket",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 1.0,
			"DEFAULT": 0.5
		},
		{
			"LABEL": "VAL- Max Bracket",
			"NAME": "valMaxBracket",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 1.0,
			"DEFAULT": 0.5
		},
		{
			"LABEL": "Dilate",
			"NAME": "dilate",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 6.0,
			"DEFAULT": 0.0
		},
		{
			"LABEL": "Blur",
			"NAME": "blur",
			"TYPE": "float",
			"MIN": 0.0,
			"MAX": 6.0,
			"DEFAULT": 0.0
		}
	],
	"PASSES": [
		{
			"TARGET": "alphaPass"
		},
		{
			"TARGET": "horizDilate"
		},
		{
			"TARGET": "vertDilate"
		},
		{
			"TARGET": "horizBlur"
		},
		{
			"TARGET": "vertBlur"
		}
	]
}*/



vec3 rgb2hsv(vec3 c);
vec3 hsv2rgb(vec3 c);

void main() {
	//	generally speaking, sample a bunch of pixels, for each sample convert color val to HSV, if luma is greater than max luma, that's the new color
	vec2		tmpCoord;
	float		maxAlpha;
	vec4		sampleColorRGB;
	vec4		src_rgb;
	
	if (PASSINDEX==0)	{
		//	the goal is to calculate a new float value for the alpha channel, and/or desaturate the color, if this pixel is "close" to the mask color
		//	get the src pixel's color (as RGB), convert to HSV values
		src_rgb = IMG_PIXEL(inputImage, gl_FragCoord.xy);
		vec3			src_hsl = rgb2hsv(src_rgb.rgb);
		//	convert the passed color (which is RGB) to HSV values
		vec3			color_hsl = rgb2hsv(mask_color.rgb);
		
		
/*			-minBracket	-tolerance	color_hsl	+tolerance	+maxBracket
				|			|			|			|			|			val being examined
		----------------------------------------------------------------
				|						|						|			alpha
				1.0						0.0						1.0									*/
		
		
		float			hueAlpha;
		float			satAlpha;
		float			valAlpha;
		//	use a 'for' loop to generate the hue/sat/val alpha values
		int			i = 0;
		float		source;
		float		color;
		float		tolerance;
		vec2		bracket;
		float		alpha;
		float		min;
		float		max;
		for (i=0; i<3; ++i)	{
			source = src_hsl[i];
			color = color_hsl[i];
			if (i==0)	{
				tolerance = hueTol;
				bracket = vec2(hueMinBracket, hueMaxBracket);
			}
			else if (i==1)	{
				tolerance = satTol;
				bracket = vec2(satMinBracket, satMaxBracket);
			}
			else if (i==2)	{
				tolerance = valTol;
				bracket = vec2(valMinBracket, valMaxBracket);
			}
			
			//	if the source sat is < the mask color sat
			if (source < color)	{
				//	the min is the bracket and tolerance, the max is the mask color
				min = color - tolerance - bracket.x;
				max = color;
				//	as i go from min to max, the alpha goes from 1 to 0
				alpha = 1.0 - smoothstep(min, max, source);
			}
			//	else if the source sat is > the mask color sat
			else if (source > color)	{
				//	the min is the mask color, the max is the tolerance and bracket
				min = color;
				max = color + tolerance + bracket.y;
				//	as i go from min to max, the alpha goes from 0 to 1
				alpha = smoothstep(min, max, source);
			}
			//	else the source sat == the mask color sat, the alpha should be 0
			else
				alpha = 0.0;
			
			if (i==0)	{
				hueAlpha = alpha;
			}
			else if (i==1)	{
				satAlpha = alpha;
			}
			else if (i==2)	{
				valAlpha = alpha;
			}
		}
		
		
		//	calculate the alpha i'll be applying
		src_rgb.a = sqrt(max(hueAlpha,max(satAlpha, valAlpha)));
		
		//	if we're doing a hard cutoff on the alpha, set it to 0.0 if below it
		if ((applyCutOff) && (src_rgb.a < cutoffThresh))	{
			src_rgb.a = 0.0;
		}
		//	otherwise, desaturate the color if appropriate, use the desaturated color
		else if (hueAlpha < 1.0)	{
			//src_hsl.y = 0.0;
			src_hsl.y = mix(0.0, src_hsl.y, hueAlpha);
			src_rgb.rgb = hsv2rgb(src_hsl.xyz);
		}
		
		
		gl_FragColor = src_rgb;
		//gl_FragColor = vec4(src_rgb.a, src_rgb.a, src_rgb.a, 1.0);
	}
	
	else if (PASSINDEX==1)	{
		//	'dilate' samples on either side + the source pixel = 2*dilate+1 total samples
		for (float i=0.; i<=float(int(dilate)); ++i)	{
			tmpCoord = vec2(clamp(gl_FragCoord.x+i,0.,RENDERSIZE.x), gl_FragCoord.y);
			sampleColorRGB = IMG_PIXEL(alphaPass, tmpCoord);
			//	if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff
			if (i == 0.)	{
				maxAlpha = sampleColorRGB.a;
				src_rgb = sampleColorRGB;
			}
			//	else this isn't the first sample...
			else	{
				//	compare, determine if it's the max luma
				if (sampleColorRGB.a < maxAlpha)	{
					maxAlpha = sampleColorRGB.a;
				}
				//	do another sample for the negative coordinate
				tmpCoord = vec2(clamp(gl_FragCoord.x-i,0.,RENDERSIZE.x), gl_FragCoord.y);
				sampleColorRGB = IMG_PIXEL(alphaPass, tmpCoord);
				if (sampleColorRGB.a < maxAlpha)	{
					maxAlpha = sampleColorRGB.a;
				}
			}
		}
		gl_FragColor = vec4(src_rgb.rgb, maxAlpha);
	}
	else if (PASSINDEX==2)	{
		//	'dilate' samples up and down + the source pixel = 2*dilate+1 total samples
		for (float i=0.; i<=float(int(dilate)); ++i)	{
			tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y+i,0.,RENDERSIZE.y));
			sampleColorRGB = IMG_PIXEL(horizDilate, tmpCoord);
			//	if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff
			if (i == 0.)	{
				maxAlpha = sampleColorRGB.a;
				src_rgb = sampleColorRGB;
			}
			//	else this isn't the first sample...
			else	{
				//	compare, determine if it's the max luma
				if (sampleColorRGB.a < maxAlpha)	{
					maxAlpha = sampleColorRGB.a;
				}
				//	do another sample for the negative coordinate
				tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y-i,0.,RENDERSIZE.y));
				sampleColorRGB = IMG_PIXEL(horizDilate, tmpCoord);
				if (sampleColorRGB.a < maxAlpha)	{
					maxAlpha = sampleColorRGB.a;
				}
			}
		}
		gl_FragColor = vec4(src_rgb.rgb, maxAlpha);
	}
	else if (PASSINDEX==3)	{
		float		tmpRadius = float(int(blur));
		vec4		tmpColor;
		vec4		srcColor;
		float		totalAlpha = 0.0;
		for (float i=-1.*tmpRadius; i<=tmpRadius; ++i)	{
			tmpColor = IMG_PIXEL(vertDilate, gl_FragCoord.xy+vec2(i,0.0));
			totalAlpha += tmpColor.a;
			if (i==0.0)
				srcColor = tmpColor;
		}
		totalAlpha /= ((tmpRadius*2.)+1.);
		gl_FragColor = vec4(srcColor.r, srcColor.g, srcColor.b, totalAlpha);
	}
	else if (PASSINDEX==4)	{
		float		tmpRadius = float(int(blur));
		vec4		tmpColor;
		vec4		srcColor;
		float		totalAlpha = 0.0;
		for (float i=-1.*tmpRadius; i<=tmpRadius; ++i)	{
			tmpColor = IMG_PIXEL(horizBlur, gl_FragCoord.xy+vec2(0.0,i));
			totalAlpha += tmpColor.a;
			if (i==0.0)
				srcColor = tmpColor;
		}
		totalAlpha /= ((tmpRadius*2.)+1.);
		
		if (showAlpha)
			gl_FragColor = vec4(totalAlpha, totalAlpha, totalAlpha, 1.0);
		else
			gl_FragColor = vec4(srcColor.r, srcColor.g, srcColor.b, totalAlpha);
	}
}




vec3 rgb2hsv(vec3 c)	{
	vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
	//vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
	//vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
	vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
	vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
	
	float d = q.x - min(q.w, q.y);
	float e = 1.0e-10;
	return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

vec3 hsv2rgb(vec3 c)	{
	vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
	vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
	return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
wellsley
Posts: 8
Joined: Fri Aug 14, 2015 8:38 am

Re: Removing background of image to use in Magic Module

Post by wellsley »

Thanks so much for putting the effort into your reply, though I must admit this is a bit above my head, I have managed to knock out the background on Photoshop, as long as there are quite distinctive boundaries, I guess it will do me for now. I might have a look at your fix later down the line
Cheers
Kvasnik
Posts: 67
Joined: Thu Feb 05, 2015 1:09 am

Re: Removing background of image to use in Magic Module

Post by Kvasnik »

Hi wellsley, if you have a still image (not a video), then it is best to make the background transparent in an editing program such as photoshop (you can also use free programs such as GIMP).

Generally, you need to create an image with (at least) two layers, and the bottom layer will be a transparent layer (also called an 'aplha layer' or sometimes 'alpha channel'). If you then save the image as the .png type (instead of .jpg) then the transparent layer will be saved with the image and when you import it into magic and it will be transparent where you designated.

You should get used to creating transparent images as it's a very useful part of playing with graphics. Good luck!
wellsley
Posts: 8
Joined: Fri Aug 14, 2015 8:38 am

Re: Removing background of image to use in Magic Module

Post by wellsley »

Thanks mate, appreciate you taking the time to post, I have Photoshop elements and am just gettin to grips with using it, and yes this does seem to be the most traight forward method, I have just been testing it and I have been saving the file as a psd file and that seems to be working ok at the moment, admittedly I have been working with quite high contrast images, so just using the magic wand tool has been adequate (so far)
Post Reply