【问题标题】:How to Implement a Census Transform in MATLAB如何在 MATLAB 中实现人口普查变换
【发布时间】:2020-04-03 18:02:15
【问题描述】:

我想在 MATLAB 中在每个过滤器窗口的中心像素处执行 Census 变换,如下所示:

如果图片没有出现,另外一个链接:https://i.ibb.co/9Y6LfSL/Shared-Screenshot.jpg

我对代码的初步尝试是:



function output =census(img,census_size)
img_gray = rgb2gray(img);
[y,x]=size(img_gray);          
borders = floor(census_size/2); % limit to exclude image borders when filtering

for(iy = 1+borders : y-borders)
    for(ix = 1+borders : x-borders)
        f=img_gray(iy-borders:iy+borders,ix-borders:ix+borders);
        iix=ix-borders;
        iiy=iy-borders;
     %   shift=bitsll(img_out(iiy,iix),1);
        img_out(iiy,iix)= % Must be Implemented with census

    end
end
%normalised_image = img_out ./ max(max(img_out)) ;
output=img_out;
imshow(normalised_image);

end

第二个 for 循环中的 iix 和 iiy 代表我当前的中心像素位置。 f 是我当前的过滤器窗口。

除了与窗口的其他像素进行比较操作外,我需要将每个比较结果设置为逻辑 1/0,并将总结果(我猜是通过移位)扩展为 8 位数据,然后将此二进制数转换为一个十进制数。我如何在 MATLAB 中以实用的方式做到这一点? 我在 Python 中检查过这个:https://stackoverflow.com/a/38269363/12173333

但无法在 MATLAB 中进行相似性分析。

【问题讨论】:

  • 天真的方法是在你的 2 个循环中添加另外 2 个循环,用于我们像素的邻居。试试看,然后你就可以开始思考实用/快速的方法了
  • 我想我可以做到,我可以通过将中心像素与相邻像素进行比较来形成新的逻辑窗口。我现在正在考虑如何通过从最低行开始左移、省略中心像素并设置中心像素的值来扩展我的二进制结果。例如,如果我的逻辑数组是 [ 1 0 0; 0 中心 1 ; 1 1 0] 我的中心应该等于 uint8(0 1 1 1 0 0 0 1)

标签: matlab image-processing binary filtering


【解决方案1】:

如果你有图片处理工具箱可以使用blockproc:

%Load your image
I = imread('https://i.stack.imgur.com/9oxaQ.png');

%Creation of the census transform function
fun = @(B) [128 64 32 16 0 8 4 2 1]*(B.data(:)>B.data(2,2));

%Process the image, block-by-block with overlap, force the result to be of type uint8
I2 = uint8(blockproc(I.',[1 1],fun,'BorderSize',[1,1],'TrimBorder',0)).'

这里 blockproc 配置为 3x3 窗口(有重叠)并适用于灰度图像。函数fun 检查块的哪个部分严格大于块的中心。我们得到一个1x9 逻辑向量。然后我将此向量与[128 64 32 16 0 8 4 2 1](二进制到十进制转换)相乘。

更新:

线性代数优化

对于随机窗口大小,您可以使用:

I = imread('https://i.stack.imgur.com/9oxaQ.png');

w   = 5;                                              % windows size, any odd number between 3 and 31.
b2d = 2.^[w^2-1:-1:ceil(w^2/2),0,floor(w^2/2):-1:1]   % binary to decimal vector
cen = ceil(w/2);                                      % center position

%Creation of the census transform function
fun = @(B) b2d*(B.data(:)>B.data(cen,cen));

%Process the image, block-by-block with overlap
I2 = blockproc(I.',[1 1],fun,'BorderSize',[cen-1,cen-1],'TrimBorder',0).'/sum(b2d)

输入:

输出:

【讨论】:

  • 谢谢!如果我使用更大的窗口大小,我应该将中心更改为 (floor(row/2) + 1, floor(col/2) + 1) ?此外,你不认为我将输出转换后的图像标准化更好吗?为了更好地计算图像深度中匹配块算法的汉明(基于 0 或 1 个像素值)距离?
  • 检查我的编辑,可以选择窗口大小并标准化输出。窗口大小应该总是奇数。并注意到,例如,窗口大小 = 7,该算法已经处理了大小为 2^(7^2-1) 或 2^48 的值。如果窗口太大,你会得到溢出。
  • 理论上最大窗口大小可以是31。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-07
  • 2013-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-01
  • 1970-01-01
相关资源
最近更新 更多