1

我打电话给for循环中的一些图像,然后对这些图像进行一些处理。之后,我使用step函数在视频播放器中显示这些帧及其蒙版。如何将边界添加到蒙版图像内的对象?另外,如何使边界更加粗糙,并在掩模图像中绘制每个斑点在掩模中的质心?以下是代码的粗略草图。如何在step()函数内调用的视频帧上绘制边界和质心

videoPlayer = vision.VideoPlayer(); 
    maskPlayer = vision.VideoPlayer(); 
    for ii = 1:nfiles 
    filenameii = [............] 
    frame= imread(filenameii); 
    mask = dOB(frame,BackgroundImg); 
% some processing on the images 
    mask= bwareaopen(mask,27); 
    boundaries = bwboundaries(mask,'noholes'); 
    B=boundaries{1}; 
    Centroid = regionprops(mask,'centroid'); 
    Centroids = cat(1, Centroid.Centroid); 
    plot(B(:,2),B(:,1),'g','LineWidth',3); 
    plot(Centroids(:,1), Centroids(:,2), 'r+', 'MarkerSize', 10); step(videoPlayer,frame); 
    step(maskPlayer, mask); 

P.S:我知道如何显示它使用hold on一个数字,但我想在图像上直接完成这件事在视频播放器显示它之前。任何指导将不胜感激。

回答

2

在将视频显示在视频播放器中之前,只需简单地在屏蔽上绘制像素。你有什么工作,但它会为面具玩家绘制图形中的边界。因此,请从bwboundaries中检测出您的边界,从这些坐标创建线性索引,并将图像中的值设置为白色。甚至可以更简单的是取出检测到的掩码并使用bwperim自动生成一个包含斑点边界的掩码。我还看到您正在填充面罩的孔,因此您可以直接在后处理的输出中使用imfill,以便它为您提供图像而不是坐标。然后,您将使用此蒙版直接将图像索引到您的图像中,并将blob边界的坐标设置为所需的颜色。如果您希望使周边更粗,则使用适当大小的方形结构元素进行简单图像膨胀将有所帮助。只需将此结构化元素的邻域的大小定义为您所需的周边厚度即可。最后,如果要将质心插入蒙版,并且具有MATLAB计算机视觉系统工具箱,请使用insertMarker函数,以便可以为每个质心使用一组点并将它们直接放在图像中。但是,您必须确保将掩码从logical更改为更适合图像的数据类型。 uint8应该可以工作。因此,将图像转换为此类型,然后将所有非零值乘以255以确保白色保持在蒙版中。用insertMarker,你想插入大小为10的红色加号,所以我们需要确保我们呼叫insertMarker来反映这一点。另外,因为你想要一个彩色图像,你将不得不人为地使你的面具变成彩色,并且为每个飞机单独绘制你想要的颜色。既然你想要绿色,这对应于(0,255,0)的RGB值。

因此,我修改了您的代码,以便它可以执行此操作。另外,我已经计算了填充的面膜的质心,而不是原来的面膜。我们不想错误地报告有间隙的物体的质心...除非这是你的目标,但让我们假设你不是:

videoPlayer = vision.VideoPlayer(); 
maskPlayer = vision.VideoPlayer(); 

% New - Specify colour you want 
clr = [0 255 0]; % Default is green 

% New - Define thickness of the boundaries in pixels. 
thickness = 3; 

% New - Create structuring element 
se = strel('square', thickness); 

for ii = 1:nfiles 
    filenameii = [............] 
    frame = imread(filenameii); 
    mask = dOB(frame, BackgroundImg); 
    % some processing on the images 
    mask = bwareaopen(mask,27); 
    %boundaries = bwboundaries(mask,'noholes'); 
    %B=boundaries{1}; 

    % New code - fill in the holes 
    mask = imfill(mask, 'holes'); 

    Centroid = regionprops(mask,'centroid');  

    % New code - Create a boundary mask 
    mask_p = bwperim(mask, 8); 

    % New code - Make the boundaries thicker 
    mask_p = imdilate(mask_p, se); 

    % New code - create a colour image out of the mask 
    [red, green, blue] = deal(255*uint8(mask)); 

    % Paint the perimeter of the blobs in the desired colour 
    red(mask_p) = clr(1); green(mask_p) = clr(2); blue(mask_p) = clr(3);   

    Centroids = cat(1, Centroid.Centroid); 
    %plot(B(:,2),B(:,1),'g','LineWidth',3); 
    %plot(Centroids(:,1), Centroids(:,2), 'r+', 'MarkerSize', 10); 

    % New - Make mask into RGB image for marker painting and to 
    % show to the user 
    mask_p = cat(3, red, green, blue); 

    % New - Insert the centroids directly in the mask image 
    mask_p = insertMarker(mask_p, Centroids, '+', 'color', 'r', 'size', 10); 

    step(videoPlayer, frame); 

    % New - Show new mask in the player 
    step(maskPlayer, mask_p); 
end 
+0

非常感谢您的回应。这确实在播放器中显示blob的边界,但是它显示了具有边界的原始图像而不是二进制图像。我想要在二进制图像周围显示边界。你能告诉我为什么这样吗?另外我想知道使用bwboundaries和bwperim的区别是什么。 – BlueBee

+0

啊,我以为你想在原始图像,而不是二进制图像。我会更新我的帖子。 'bwboundaries'和'bwperim'之间的区别在于'bwboundaries'将blob的边界看作一组'(x,y)'点。 'bwperim'作为图像返回blob的边界。此图像对绘制像素以在图上显示该图像至关重要。 – rayryeng

+0

非常感谢,它的工作现在完美:)。是否可以增加边界/边界的宽度?此外,如何将遮罩图像顶部的质心绘制为当前显示在单独窗口中的图形。 – BlueBee