从图像中删除背景

信息处理 图像处理 视频处理 C# 背景减法
2022-01-28 16:50:40

我想从图像中删除背景。假设我有这样的背景:

示例背景图像.

然后我把笔式驱动器和tippex放在上面。

带有物体的图像.

是否可以从第二张图片中删除背景图片?如果是这样,那我该怎么做?

我正在使用 AForge.NET 框架。

更新

我想删除这篇研究论文中的背景。有这种工作的图书馆吗?

2个回答

由于您事先已经知道背景图像,因此应该很简单。我之前做过很多背景减法。这是一个通过比较去除背景的示例。

    if (newBitmap.Width == backgroundBitmap.Width && newBitmap.Height == backgroundBitmap.Height)
    {
        for(int x = 0; x < newBitmap.Width; x++)
        {
            for (int y = 0; y < newBitmap.Height; y++)
            {
                Color firstPixel = newBitmap.GetPixel(x, y);
                Color SecondPixel = backgroundBitmap.GetPixel(x, y);  

                int Totalfirst = (int)((firstPixel.R * .3) + (firstPixel.G * .59) + (firstPixel.B * .11));
                int Totalsecond = (int)((SecondPixel.R * .3) + (SecondPixel.G * .59) + (SecondPixel.B * .11));
                if (Totalfirst < Totalsecond )
                {

                    Color WhiteColor = Color.FromArgb(0, 0, 0);
                    newBitmap.SetPixel(x, y, WhiteColor);
                }
                else
                {
                    Color SameColor = Color.FromArgb(firstPixel.R, firstPixel.G, firstPixel.B);
                    newBitmap.SetPixel(x, y, SameColor);
                }

            }
        }
    }
    FinalImage = newBitmap; // after substaction of back ground.
}

这段代码只是我当时做的一个程序的复制和粘贴。请注意,newBitmap 是对象和背景的图像,即您的第二张图片。虽然 backgroundBitmap 很好,但背景。

将此用作您的代码在此段中的外观的参考。应该够好了。

另外,我是这个网站的新手(我在这里的第一篇文章),但我认为对于图像处理问题,您可以下次发布到https://stackoverflow.com/questions,会有更多人帮助您。

如果这种方法不起作用,请告诉我,因为我还有其他方法。但从你的问题来看,这应该足够了。

从算法的角度来看,减法是最简单的方法。

  1. 在两个图像上运行特征检测算法(如 SIFT 或 SURF)以对齐它们
  2. 在此阶段应用任何增强操作,例如镜头失真消除、照明校正或其他。
  3. 从测试图像中简单地减去背景图像。
  4. 对减去的图像执行模糊或中值过滤。这将减轻减法产生的噪音。
  5. 在此图像上运行阈值工具以生成前景蒙版。
  6. 可选择模糊前景蒙版以平滑边缘。
  7. 将蒙版应用于您的测试图像,只有前景可见。

以下是一些粗略地完成此操作的丑陋代码。如果我有时间,我会清理代码,或者也许其他人可以为我清理。我使用了 OpenCV,它非常有能力做你想做的事,尽管你需要使用 .NET 绑定。

import cv
import cv2
import numpy as np
import sys

# Align images with cv2
imgBack = cv2.imread("Background.png")
imgTest = cv2.imread("Test.png")

detector = cv2.FeatureDetector_create("SURF")
descriptor = cv2.DescriptorExtractor_create("BRIEF")
matcher = cv2.DescriptorMatcher_create("BruteForce-Hamming")

# the matcher works on single channel images
grayBack = cv2.cvtColor(imgBack, cv2.COLOR_RGB2GRAY)
grayTest = cv2.cvtColor(imgTest, cv2.COLOR_RGB2GRAY)

# Compute magic (I found this code elsewhere 
kp1 = detector.detect(grayBack)
kp2 = detector.detect(grayTest)

k1, d1 = descriptor.compute(grayBack, kp1)
k2, d2 = descriptor.compute(grayTest, kp2)

matches = matcher.match(d1, d2)

dist = [m.distance for m in matches]
if len(dist) == 0:
    print "No Suitable matches found!"
    sys.exit(1)

mean_dist = sum(dist) / len(dist)
threshold_dist = mean_dist * 0.5

good_matches = [m for m in matches if m.distance < threshold_dist]

h1, w1 = grayBack.shape[:2]

matches = []
for m in good_matches:
    matches.append((m.queryIdx, m.trainIdx))

if len(good_matches) > 0:
    p1 = np.float32( [k1[i].pt for i, j in matches] )
    p0 = np.float32( [k2[j].pt for i, j in matches] )
    H, mask = cv2.findHomography(p0, p1, cv2.RANSAC)

    output = cv2.warpPerspective(imgTest, H, (w1, h1))
# End Magic

cv2.imwrite("Test-Warped.png", output)

imgBack = cv.LoadImage("Background.png")
imgTest = cv.LoadImage("Test-Warped.png")

diff = cv.CloneImage(imgBack)
grayDiff = cv.CreateImage(cv.GetSize(imgBack), cv.IPL_DEPTH_8U, 1)

# Perform simple substraction    
cv.AbsDiff(imgBack, imgTest, diff)
cv.CvtColor(diff, grayDiff, cv.CV_RGB2GRAY)

# Get our threshold and expand it a little to clean the edges
cv.Threshold(grayDiff, grayDiff, 40, 255, cv.CV_THRESH_BINARY)
cv.Dilate(grayDiff, grayDiff, None, 6)
cv.Erode(grayDiff, grayDiff, None, 2)

# Copy the test image and mask with our threshold
fore = cv.CreateImage(cv.GetSize(imgBack), cv.IPL_DEPTH_8U, 3)
cv.Copy(imgTest, fore, grayDiff)

cv.SaveImage("Threshold.png", grayDiff)
cv.SaveImage("Foreground.png", fore)

算法找到的中间阈值 最终(粗)提取的前景