MATLAB-灰度图像中的小鼠分割,对阴影具有不变性
MATLAB- mices segmentation in grayscale images, which is invariant to shadows
找了两三天,还是没有找到解决问题的方法。
我想创建一个没有阴影的鼠标分段。问题是,如果我设法去除阴影,我也会去除尾巴和足部,这是一个问题。阴影来自鼠标所在的竞技场的墙壁。
我想从灰度图像中去除阴影,但我不知道该怎么做。首先我去掉了图片的背景,得到了下图。
edit1 : 感谢您的回答它在阴影不接触鼠标时运行良好。这就是我得到的:
来自这张原始图片:
我正在从一个 tif 文件中提取每一帧,并为每一帧应用您的代码。这是我使用的代码:
for k=1:1000
%reads image
I = imread('souris3.tif',k);
%first stage: perform thesholding and fill holes
seg = I >20000;
seg = imfill(seg,'holes');
%fixes the missing tail problem
%extract edges, and add them to the segmentation.
edges = edge(I);
seg = seg | edges;
%fill holes (again)
seg = imfill(seg,'holes');
%find all the connected components
CC = bwconncomp(seg,8);
%keeps only the biggest CC
numPixels = cellfun(@numel,CC.PixelIdxList);
[biggest,idx] = max(numPixels);
seg = zeros(size(edges));
seg(CC.PixelIdxList{idx}) = 1;
imshow(seg);
end
我用命令impixelinfo
选择20000作为step,因为图像在uint16
并且是鼠标的平均值。
这是 link 如果你想要 tif 文件:
感谢您的帮助。
我建议采用以下方法:
- 对图像执行阈值处理,得到一个包含大部分老鼠body但没有尾巴和腿的蒙版。
- 使用MATLAB的imfill函数进行孔洞填充。在这个阶段,分割几乎是完美的,除了尾巴的一部分缺失。
- 使用边缘图来找到尾巴的边界。这可以通过将边缘图添加到分割并再次执行孔填充来完成。在此阶段只保留最大的连通分量。
代码:
%reads image
I = rgb2gray(imread('mSWm4.png'));
%defines thersholds (you may want to tweak these thresholds, or find
%a way to calculate it automatically).
FIRST_STAGE_THRESHOLD = 70;
IM_BOUNDARY_RELEVANCE_THRESHOLD = 10;
%perform thesholding and fill holes, the tail is still missing
seg = I > FIRST_STAGE_THRESHOLD;
seg = imfill(seg,'holes');
%second stage fix the missing tail problem:
%extract edges from relevant areas (in which the matter is not too dark), and add them to the segmentation.
%the boundries of the image which are close enough to edges are also considered as edges
edges = edge(I);
imageBoundries = ones(size(I));
imageBoundries(2:end-1,2:end-1) = 0;
relevantDistFromEdges = bwdist(edges) > IM_BOUNDARY_RELEVANCE_THRESHOLD;
imageBoundries(bwdist(edges) > IM_BOUNDARY_RELEVANCE_THRESHOLD) = 0;
seg = seg | (edges | imageBoundries);
%fill holes (again) and perform noise cleaning
seg = imfill(seg,'holes');
seg = getBiggestCC(imopen(seg,strel('disk',1)));
getBiggestCC 函数:
function [ res ] = getBiggestCC(mask)
CC = bwconncomp(mask,8);
numPixels = cellfun(@numel,CC.PixelIdxList);
[~,idx] = max(numPixels);
res = zeros(size(mask));
res(CC.PixelIdxList{idx}) = 1;
end
结果
每个阶段的结果:
结果
图片 1 结果:
图片 2 结果:
另一种视图(分段为红色):
找了两三天,还是没有找到解决问题的方法。
我想创建一个没有阴影的鼠标分段。问题是,如果我设法去除阴影,我也会去除尾巴和足部,这是一个问题。阴影来自鼠标所在的竞技场的墙壁。
我想从灰度图像中去除阴影,但我不知道该怎么做。首先我去掉了图片的背景,得到了下图。
edit1 : 感谢您的回答它在阴影不接触鼠标时运行良好。这就是我得到的:
来自这张原始图片:
我正在从一个 tif 文件中提取每一帧,并为每一帧应用您的代码。这是我使用的代码:
for k=1:1000
%reads image
I = imread('souris3.tif',k);
%first stage: perform thesholding and fill holes
seg = I >20000;
seg = imfill(seg,'holes');
%fixes the missing tail problem
%extract edges, and add them to the segmentation.
edges = edge(I);
seg = seg | edges;
%fill holes (again)
seg = imfill(seg,'holes');
%find all the connected components
CC = bwconncomp(seg,8);
%keeps only the biggest CC
numPixels = cellfun(@numel,CC.PixelIdxList);
[biggest,idx] = max(numPixels);
seg = zeros(size(edges));
seg(CC.PixelIdxList{idx}) = 1;
imshow(seg);
end
我用命令impixelinfo
选择20000作为step,因为图像在uint16
并且是鼠标的平均值。
这是 link 如果你想要 tif 文件:
感谢您的帮助。
我建议采用以下方法:
- 对图像执行阈值处理,得到一个包含大部分老鼠body但没有尾巴和腿的蒙版。
- 使用MATLAB的imfill函数进行孔洞填充。在这个阶段,分割几乎是完美的,除了尾巴的一部分缺失。
- 使用边缘图来找到尾巴的边界。这可以通过将边缘图添加到分割并再次执行孔填充来完成。在此阶段只保留最大的连通分量。
代码:
%reads image
I = rgb2gray(imread('mSWm4.png'));
%defines thersholds (you may want to tweak these thresholds, or find
%a way to calculate it automatically).
FIRST_STAGE_THRESHOLD = 70;
IM_BOUNDARY_RELEVANCE_THRESHOLD = 10;
%perform thesholding and fill holes, the tail is still missing
seg = I > FIRST_STAGE_THRESHOLD;
seg = imfill(seg,'holes');
%second stage fix the missing tail problem:
%extract edges from relevant areas (in which the matter is not too dark), and add them to the segmentation.
%the boundries of the image which are close enough to edges are also considered as edges
edges = edge(I);
imageBoundries = ones(size(I));
imageBoundries(2:end-1,2:end-1) = 0;
relevantDistFromEdges = bwdist(edges) > IM_BOUNDARY_RELEVANCE_THRESHOLD;
imageBoundries(bwdist(edges) > IM_BOUNDARY_RELEVANCE_THRESHOLD) = 0;
seg = seg | (edges | imageBoundries);
%fill holes (again) and perform noise cleaning
seg = imfill(seg,'holes');
seg = getBiggestCC(imopen(seg,strel('disk',1)));
getBiggestCC 函数:
function [ res ] = getBiggestCC(mask)
CC = bwconncomp(mask,8);
numPixels = cellfun(@numel,CC.PixelIdxList);
[~,idx] = max(numPixels);
res = zeros(size(mask));
res(CC.PixelIdxList{idx}) = 1;
end
结果
每个阶段的结果:
结果 图片 1 结果:
图片 2 结果:
另一种视图(分段为红色):