🔥 Programming/OpenCV
[OpenCV4] C# OpenCV4 배경색 변경
스쳐가는비
2022. 11. 10. 21:33
배경색 변경
OpenCV4를 사용하다보면, 이미지를 병합시켜야할때와, 병합 이후 배경이 함께나와 제거해야할 경우가 많다.
실시간으로 병합되는 이미지를 배경 이미지 내에서의 위치를 변경시켜야할 때,
그 이미지의 배경을 지워주지 않으면 원활한 이미지 병합을 했다고 볼 수 없다.
배경 자체를 지우는 방법도 있지만, 우선 배경 색 변경을 하는 방법에 대해 알아보자.
변경할 이미지는 배경이 검은색인 볼링공 이미지이다.
해당 이미지의 배경색을 흰색으로 만들 예정이다.
C#에서 포인터를 사용하려면 unsfae를 이용하여야 한다.
그리고 비트맵의 Lock Bits를 통해 Data를 가져오고, Scan0을 통해 포인터 주소를 구한다.
이후 비트맵의 한 픽셀의 RGB 값이 나오게 되는데 이 부분을 수정을 통해 색을 바꿔 보도록 하자.
아래는 결과 이미지이다.
Code ( C# )
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RemoveBackground
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
pictureBox1.Image = ImageProcessing(Properties.Resources.bowling).ToBitmap();
}
private Mat ImageProcessing(Bitmap bmp)
{
Mat bowling = new Mat();
Cv2.ImShow("Before", Properties.Resources.bowling.ToMat());
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
Color removeTargetColor = Color.Black;
int changeColor = Color.Transparent.ToArgb();
double threshold = 100;
unsafe
{
int* length = (int*)data.Scan0 + bmp.Height * bmp.Width;
for (int* p = (int*)data.Scan0; p < length; p++)
{
Color pixelColor = Color.FromArgb(*p);
double r = Math.Pow((double)(pixelColor.R - removeTargetColor.R), 2.0);
double g = Math.Pow((double)(pixelColor.G - removeTargetColor.G), 2.0);
double b = Math.Pow((double)(pixelColor.B - removeTargetColor.B), 2.0);
double delta = Math.Sqrt(r + g + b);
if (delta <= threshold)
*p = changeColor;
}
bmp.UnlockBits(data);
bowling = bmp.ToMat();
bmp.Dispose();
}
return bowling;
}
}
}