I recently encountered a need to remove the black background of a picture, as shown in the following figure:
If you use OPENCV, plus some image processing algorithms, you can remove any background. But because this requirement is to remove the black background, it feels unnecessary to use any more complicated algorithms.
So I planned to search on the Internet, but I didn t find it at first, but I searched for an idea on how to remove the black background with ps: remove the black background of the picture and output it as a transparent png (algorithm and tool)
But it mainly talks about the operation with PS, and the principle mentioned in it is not very clear. So I plan to think of an algorithm by myself.
Wrong idea
The first idea is to determine whether the color is black (r = 0, g = 0, b = 0), if it is black, set the transparency of the pixel to 0. But the result is definitely unsatisfactory, as shown in the following figure:
As a result, none of the pixels are set to be fully transparent. why? Because this background is not pure black, it is just black. For example, the pixel value (r=15, g=5, b=5) is not pure black, but the human eye feels black.
The right idea
After thinking about it, I came up with another idea, that is, the darker the color, the lower the transparency setting. Therefore, you only need to remove the larger value of the three channels in the pixel and set it to the transparency of the color. For example, the pixel value (r=15, g=5, b=5), then the transparency can be set to Math.max( 15,5,5) = 15.
Here is the sample code:
function removeBlackBackgroundFunc(frameImageData) {
let data = frameImageData.data;
for(var i = 0;i < data.length/4; i ++){
var index = i * 4;
var r = data[index],g = data[index + 1],b = data[index + 2],a = data[index + 3];
var max = Math.max(r,g,b);
data[index + 3] = max;
if(r == 0 && g == 0 && b == 0){
data[index + 3] = 0;
}
}
return frameImageData;
}
Draw the picture with the black background removed onto a blue background, the code is as follows:
ctx.globalCompositeOperation = 'destination-over';
ctx.fillStyle = 'rgba(0,0,255,1.0)';
ctx.fillRect(0,image.height,image.width,image.height + 10);
The final figure is shown below:
Principle summary
Since I am using the browser JavaScript programming language, I am using the canvas function on the browser. First draw the picture on the canvas, and then you can get each pixel through the related methods of the canvas, and then use the method of removing the black background to manipulate the pixels.
If readers are not clear about canvas-related knowledge points, it is recommended to learn relevant knowledge, and interested readers are also recommended to subscribe to the column:
Canvas Advanced Advanced xiaozhuanlan.com/canvas , relevant knowledge will be introduced in the column.
The principle of removing the black background, in popular words, "the darker the pixel, the more transparent".
There may be some differences in the implementation details for different methods. For example, we can consider taking the maximum value of the pixel and transforming the linear space to the nonlinear space, such as the following code:
var adjust = 0.8;
data[index + 3] = Math.pow(max/255,adjust) * 255;
The final effect will be slightly different in details, you can adjust adjust to see the difference in details.
Welcome to pay attention to the public account "ITman Uncle Biao". Uncle Biao, with more than 10 years of development experience, is currently the company's system architect, technical director, technical trainer, and career planner. He has in-depth research in computer graphics, WebGL, and front-end visualization. Have a strong interest in programmers' thinking ability training and training, and programmers' career planning.