从分割输出构建训练图像的最有效方法是什么?
What is the most efficient way to construct training images from segmentation output?
我想从分水岭变换输出中制作训练图像,以便在每个单元格中都有一个图像片段。我怎样才能以最有效的方式做到这一点?
更多详情:
假设L
是分水岭分割的输出:
L =
1 1 2
1 0 2
1 2 2
0 0 2
- 0 是背景
- 1为段号1,2为段号2,依此类推
我想用两个图像构建一个单元格,每个图像包含一个片段:
cell1=
1 1
1 0
1 0
cell2=
0 2
0 2
2 2
0 2
我知道我可以用一些 for 循环和 if 条件来做到这一点,但是我需要一个计算成本最低的解决方案。也许 Matlab 有这个任务的内置函数?
既然你问的是一种有效的方法,我认为下面的解决方案应该能很好地工作。尽管它使用 1 个 for 循环,但它只循环 N
次,其中 N
是分水岭变换输出中的 number of segments
,这对于图像分割通常非常低(N=2例如)。
N = max(L(:)); %//number of segments
C = cell(N,1); %//create Cell Array
[height, width] = size(L); %//get dimensions of image
for target=1:N %//for each segment..
%//search column-wise to get first and last column index
col_start = ceil(find(L==target,1)/height);
col_end = ceil(find(L==target,1,'last')/height);
%//search row-wise to get first and last row index
row_start = ceil(find(L.'==target,1)/width);
row_end = ceil(find(L.'==target,1,'last')/width);
T = L(row_start:row_end , col_start:col_end); %//image segment of bounding box
T(T~=target) = 0; %//set non-targets to 0
C{target} = T; %//add to cell array
end
我在这里写了一个 clean / short 解决方案,但我不知道它比 Lincoln 的解决方案快还是慢。只需尝试使用 tic/toc
.
function A = removePadding(L, x)
A = (L==x);
A(all(A == 0, 2), :)=[];
A(:, all(A == 0, 1))=[];
end
L = [1 1 2;1 0 2; 1 2 2; 0 0 2];
u = unique(L(:))
arrayfun(@(x) removePadding(L, x)*2, u(2:end), 'UniformOutput', false)
将输出:
ans =
{
[1,1] =
1 1
1 0
1 0
[2,1] =
0 2
0 2
2 2
0 2
}
注意:函数removePadding
将删除所有只包含零的rows/columns。这意味着如果一个区域无法连接,它将无法工作,因为中间 rows/cols 也将被删除。但我认为这不会发生在你的情况下,因为分水岭 (IMO) 只会 return 如果区域完全连接则相同的区域索引(例如区域 1 为 1)。
速度测试:
首先,定义 L 和 my 函数。
现在测试:
>> tic;
for i = 1:1000
u = unique(L(:));
B = arrayfun(@(x) removePadding(L, x)*2, u(2:end), 'UniformOutput', false);
end
>> toc
Elapsed time is 4.89563 seconds.
现在您可以复制此测试代码段并对其进行修改,以检查 Lincolns 的计算速度。
EDIT2:我将 Lincolns 解决方案定义为 C = myFun(L)
,然后再次 运行 速度测试:
>> tic;
>> for i = 1:1000
B = myFun(L);
end
>> toc
Elapsed time is 1.01026 seconds.
似乎快得多 :-) 即使使用 for 循环。
下面一个linner就可以搞定了;-)
U = regionprops(L, 'Image')
解决方案之间的比较(L是1200x1600像素的图像):
>> tic;
for index=1:100
U = regionprops(L, 'Image');
end
toc;
经过的时间是 20.138794 秒。
>>tic;
for index=1:100
N = max(L(:)); %//number of segments
C = cell(N,1); %//create Cell Array
[height, width] = size(L); %//get dimensions of image
for target=1:N %//for each segment..
%//search column-wise to get first and last column index
col_start = ceil(find(L==target,1)/height);
col_end = ceil(find(L==target,1,'last')/height);
%//search row-wise to get first and last row index
row_start = ceil(find(L.'==target,1)/width);
row_end = ceil(find(L.'==target,1,'last')/width);
T = L(row_start:row_end , col_start:col_end); %//image segment of bounding box
T(T~=target) = 0; %//set non-targets to 0
C{target} = T; %//add to cell array
end;
end
toc;
经过的时间是 300.744868 秒。
>> tic;
for index=1:100
u = unique(L(:));
B = arrayfun(@(x) removePadding(L, x)*2, u(2:end), 'UniformOutput', false);
end
toc;
经过的时间是 182.193148 秒。
我想从分水岭变换输出中制作训练图像,以便在每个单元格中都有一个图像片段。我怎样才能以最有效的方式做到这一点?
更多详情:
假设L
是分水岭分割的输出:
L =
1 1 2
1 0 2
1 2 2
0 0 2
- 0 是背景
- 1为段号1,2为段号2,依此类推
我想用两个图像构建一个单元格,每个图像包含一个片段:
cell1=
1 1
1 0
1 0
cell2=
0 2
0 2
2 2
0 2
我知道我可以用一些 for 循环和 if 条件来做到这一点,但是我需要一个计算成本最低的解决方案。也许 Matlab 有这个任务的内置函数?
既然你问的是一种有效的方法,我认为下面的解决方案应该能很好地工作。尽管它使用 1 个 for 循环,但它只循环 N
次,其中 N
是分水岭变换输出中的 number of segments
,这对于图像分割通常非常低(N=2例如)。
N = max(L(:)); %//number of segments
C = cell(N,1); %//create Cell Array
[height, width] = size(L); %//get dimensions of image
for target=1:N %//for each segment..
%//search column-wise to get first and last column index
col_start = ceil(find(L==target,1)/height);
col_end = ceil(find(L==target,1,'last')/height);
%//search row-wise to get first and last row index
row_start = ceil(find(L.'==target,1)/width);
row_end = ceil(find(L.'==target,1,'last')/width);
T = L(row_start:row_end , col_start:col_end); %//image segment of bounding box
T(T~=target) = 0; %//set non-targets to 0
C{target} = T; %//add to cell array
end
我在这里写了一个 clean / short 解决方案,但我不知道它比 Lincoln 的解决方案快还是慢。只需尝试使用 tic/toc
.
function A = removePadding(L, x)
A = (L==x);
A(all(A == 0, 2), :)=[];
A(:, all(A == 0, 1))=[];
end
L = [1 1 2;1 0 2; 1 2 2; 0 0 2];
u = unique(L(:))
arrayfun(@(x) removePadding(L, x)*2, u(2:end), 'UniformOutput', false)
将输出:
ans =
{
[1,1] =
1 1
1 0
1 0
[2,1] =
0 2
0 2
2 2
0 2
}
注意:函数removePadding
将删除所有只包含零的rows/columns。这意味着如果一个区域无法连接,它将无法工作,因为中间 rows/cols 也将被删除。但我认为这不会发生在你的情况下,因为分水岭 (IMO) 只会 return 如果区域完全连接则相同的区域索引(例如区域 1 为 1)。
速度测试: 首先,定义 L 和 my 函数。 现在测试:
>> tic;
for i = 1:1000
u = unique(L(:));
B = arrayfun(@(x) removePadding(L, x)*2, u(2:end), 'UniformOutput', false);
end
>> toc
Elapsed time is 4.89563 seconds.
现在您可以复制此测试代码段并对其进行修改,以检查 Lincolns 的计算速度。
EDIT2:我将 Lincolns 解决方案定义为 C = myFun(L)
,然后再次 运行 速度测试:
>> tic;
>> for i = 1:1000
B = myFun(L);
end
>> toc
Elapsed time is 1.01026 seconds.
似乎快得多 :-) 即使使用 for 循环。
下面一个linner就可以搞定了;-)
U = regionprops(L, 'Image')
解决方案之间的比较(L是1200x1600像素的图像):
>> tic;
for index=1:100
U = regionprops(L, 'Image');
end
toc;
经过的时间是 20.138794 秒。
>>tic;
for index=1:100
N = max(L(:)); %//number of segments
C = cell(N,1); %//create Cell Array
[height, width] = size(L); %//get dimensions of image
for target=1:N %//for each segment..
%//search column-wise to get first and last column index
col_start = ceil(find(L==target,1)/height);
col_end = ceil(find(L==target,1,'last')/height);
%//search row-wise to get first and last row index
row_start = ceil(find(L.'==target,1)/width);
row_end = ceil(find(L.'==target,1,'last')/width);
T = L(row_start:row_end , col_start:col_end); %//image segment of bounding box
T(T~=target) = 0; %//set non-targets to 0
C{target} = T; %//add to cell array
end;
end
toc;
经过的时间是 300.744868 秒。
>> tic;
for index=1:100
u = unique(L(:));
B = arrayfun(@(x) removePadding(L, x)*2, u(2:end), 'UniformOutput', false);
end
toc;
经过的时间是 182.193148 秒。