【问题标题】:Removing specific parts of the image in openCV在openCV中删除图像的特定部分
【发布时间】:2017-06-08 10:45:28
【问题描述】:

我正在做一些图像处理,需要在图像中做以下任务::

图片

从这里我想移除眼睛、眉毛、嘴唇等,这样图像的平滑度就不会丢失(例如,如果眼睛被移除,那么该区域应该用相邻的颜色替换)。

我有该区域的详细信息(点)覆盖需要展平的部分(眼睛等)。如下所示::

【问题讨论】:

  • 你能分享你用来生成面部特征点的库吗?
  • @ZdaR,肯定会问。你知道我怎样才能实现我想要的吗?
  • @OddNorg Dlib 不提供额头上的点。

标签: opencv image-processing


【解决方案1】:

如果您已经有了要替换的点甚至更好的轮廓(例如在第二张图片中以绿色绘制的这些),请查看inpaint:http://docs.opencv.org/3.1.0/d1/d0d/group__photo.html#gaedd30dfa0214fec4c88138b51d678085

我认为这正是您想要的!示例见此处:https://en.wikipedia.org/wiki/Inpainting

过程很简单:

  1. 制作一个填充了您的轮廓(drawContours,厚度:CV_FILLED)的蒙版,并用它们各自的环境进行修复/替换和
  2. inpaint 带着这个面具。

我应该提一下,这仅适用于 8 位图像。

下面的(未经测试的)代码 sn-p 应该可以做到。

Mat mask = Mat::zeros(img.size(), CV_8UC1);
for (int i = 0; i < contours.size(); i++)
  drawContours(mask, contours, i, Scalar::all(255), CV_FILLED);
Mat dst;
double radius = 20;    
inpaint(img, mask, dst, radius, INPAINT_NS);
//inpaint(img, mask, dst, radius, INPAINT_TELEA);
imshow("dst", dst);
waitKey();

编辑:制作几个点的轮廓: 轮廓只是一个点向量,打包到另一个向量中。所以,解决方案应该是这样的,给定vector&lt;Point&gt; points

vector<vector<Point> > contours;
contours.push_back(points);
drawContours(mask, contours, 0, Scalar::all(255), CV_FILLED);

【讨论】:

  • 我的图像是彩色 BRG 图像,所以我需要灰度才能获得 8 位吗?
  • 8 位 1 通道或 3 通道,因此适用于您的情况。
  • 如何沿着我想要的路径绘制轮廓,如绿点所示?因为这也是我无法找到的,因为大多数轮廓默认情况下都在那里?
  • 我以为你已经画了红点和绿色轮廓,但如果不是这样......你不能简单地将点作为轮廓吗?
  • 蒙版应该是灰度的吧?使其成为 1 个频道?
【解决方案2】:

一个 Python 版本,使用简单的阈值来选择面部特征(因为我没有那些绿色轮廓),然后进行修复,如 Phann 的回答中所述:

import cv2
import numpy as np

def get_inpainted(img):
    gs = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gs, 70, 1, cv2.THRESH_BINARY)
    mask_features = 1 - thresh #1 for the dark pixels, 0 everywhere else
    #enlarge the mask a little bit...
    mask_features = cv2.dilate(mask_features, np.ones((8, 8), np.uint8))
    return cv2.inpaint(img, mask_features, 8, cv2.INPAINT_NS)

img_source = cv2.imread("test_images/face.jpg")
img_dest = img_source[:]

#manually select two areas of interest
img_dest[158:276, 34:213] = get_inpainted(img_source[158:276, 34:213]) #eyebrows to nostrils
img_dest[278:343, 68:190] = get_inpainted(img_source[278:343, 68:190]) #mouth

cv2.imwrite("test_images/face_inp.jpg", img_dest)

所以我们把你第一张照片中的那个人(左)变成了一个不露面的可怕家伙(右):

【讨论】:

  • 这条线做什么 :: mask_features = 1 - thresh ?
  • 它反转二进制掩码,在前一行计算。
  • 嗨,我正面临修复问题,因为它不能与通用面正常工作,因为相邻像素有时是黑色的。 ibb.co/nKcz0v 就像图片中的头发在附近并且它出现了。知道如何解决吗?
猜你喜欢
  • 2018-02-08
  • 2011-01-11
  • 1970-01-01
  • 2020-05-28
  • 1970-01-01
  • 2018-10-01
  • 2021-01-20
  • 2020-10-17
  • 2014-09-04
相关资源
最近更新 更多