我目前正在做一个项目,我正在尝试使用 Emgu CV 根据 C# 中的手部血管模式来识别人类。首先使用自适应阈值函数处理手部的灰度图像。现在我想使用形态学操作创建图像的蒙版。目的是去除图像中的噪声。这是自适应阈值图像:
请指导我应该使用哪个功能以及如何使用。
我目前正在做一个项目,我正在尝试使用 Emgu CV 根据 C# 中的手部血管模式来识别人类。首先使用自适应阈值函数处理手部的灰度图像。现在我想使用形态学操作创建图像的蒙版。目的是去除图像中的噪声。这是自适应阈值图像:
请指导我应该使用哪个功能以及如何使用。
这里的代码是 C++。移植到 C# 应该不难,因为它主要是 OpenCV 函数调用。您可以将其用作指导方针。对于那个很抱歉。
您可以应用具有小内核的开放操作来消除大部分噪声:
Mat1b opened;
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));
morphologyEx(thresholded, opened, MORPH_OPEN, kernel);
如您所见,仍然存在一些噪声,您无法通过其他形态学操作将其移除。您可以简单地将最大的 blob 视为正确的 blob(此处为绿色):
然后你可以填充手的内侧(这里是灰色的):
并将原始图像中的所有值设置为 0,其中对应的蒙版与图像内部的颜色不同:
这是完整的代码(同样,它是 C++):
#include <opencv2/opencv.hpp>
using namespace cv;
int main(int, char**)
{
// Load grayscale image
Mat1b thresholded = imread("path_to_image", IMREAD_GRAYSCALE);
// Get rid of JPEG compression artifacts
thresholded = thresholded > 100;
// Needed so findContours handles borders contours correctly
Mat1b bin;
copyMakeBorder(thresholded, bin, 1,1,1,1, BORDER_CONSTANT, 0);
// Apply morphological operation "close"
Mat1b closed;
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));
morphologyEx(bin, closed, MORPH_OPEN, kernel);
// Find contours
vector<vector<Point>> contours;
findContours(bin.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(-1,-1)); // Point(-1,-1) accounts for previous copyMakeBorder
// Keep largest contour
int size_largest = 0;
int idx_largest = -1;
for (int i = 0; i < contours.size(); ++i)
{
if (contours[i].size() > size_largest)
{
size_largest = contours[i].size();
idx_largest = i;
}
}
Mat3b dbg;
cvtColor(closed, dbg, COLOR_GRAY2BGR);
// Black initialized mask
Mat1b mask(thresholded.rows, thresholded.cols, uchar(0));
if (idx_largest >= 0)
{
drawContours(dbg, contours, idx_largest, Scalar(0, 255, 0), CV_FILLED);
// Draw filled polygin on mask
drawContours(mask, contours, idx_largest, Scalar(255), 1);
}
// Get a point inside the contour
Moments m = moments(contours[idx_largest]);
Point2f inside(m.m10 / m.m00, m.m01 / m.m00);
floodFill(mask, inside, Scalar(127));
Mat3b result;
cvtColor(thresholded, result, COLOR_GRAY2BGR);
result.setTo(Scalar(0), mask != 127);
imshow("Closed", closed);
imshow("Contour", dbg);
imshow("Result", result);
waitKey();
return 0;
}