在MATLAB中,我有一个256x256的RGB图像和一个经过它的3x3内核。 3x3内核计算内核中9个像素的每对组合之间的颜色 - 欧氏距离,并将最大值存储在数组中。然后它移动1个像素并执行相同的计算,依此类推。
我可以轻松编写内核在图像上的移动,以及从内核中的像素中提取RGB值。
但是,我确实无法有效地计算每对像素组合的颜色 - 欧几里德距离操作。
例如,如果我有一个3x3矩阵,其中包含以下值:
[55 12 5; 77 15 99; 124 87 2]
我需要编写一个循环,使第一个元素执行第二个,第三个...第九个元素的操作。然后第二个元素用第3个,第4个...第9个元素执行操作,依此类推,直到最后第8个元素用第9个元素执行操作。优选地,相同的像素组合不应该再次计算(就像你用第7个计算第2个,不用第2个计算第7个)。
提前谢谢。
编辑:我的代码到目前为止
K=3;
s=1; %If S=0, don't reject, If S=1 Reject first max distance pixel pair
OI=imread('onion.png');
Rch = im2col(OI(:,:,1),[K,K],'sliding')
Gch = im2col(OI(:,:,2),[K,K],'sliding')
Bch = im2col(OI(:,:,3),[K,K],'sliding')
indexes = bsxfun(@gt,(1:K^2)',1:K^2)
a=find(indexes);
[idx1,idx2] = find(indexes);
Rsqdiff = (Rch(idx2,:) - Rch(idx1,:)).^2
Gsqdiff = (Gch(idx2,:) - Gch(idx1,:)).^2
Bsqdiff = (Bch(idx2,:) - Bch(idx1,:)).^2
dists = sqrt(double(Rsqdiff + Gsqdiff + Bsqdiff)) %Distance values for all 36 combinations in 1 column
[maxdist,idx3] = max(dists,[],1) %idx3 is each column's index of max value
if s==0
y = reshape(maxdist,size(OI,1)-K+1,[]) %max value of each column (each column has 36 values)
elseif s==1
[~,I]=max(maxdist);
idx3=idx3(I);
n=size(idx3,2);
for i=1:1:n
idx3(i)=a(idx3(i));
end
[I,J]=ind2sub([K*K K*K],idx3);
for j=1:1:a
[M,N]=ind2sub([K*K K*K],dists(j,:));
M(I,:)=0;
N(:,J)=0;
dists(j,:)=sub2ind; %Incomplete line, don't know what to do here
end
[maxdist,idx3] = max(dists,[],1);
y = reshape(maxdist,size(OI,1)-K+1,[]);
end
答案 0 :(得分:4)
如果我正确理解了这个问题,那么您希望在滑动3x3
窗口内形成唯一的成对组合,执行欧几里德距离计算,考虑所有三个通道,我们称之为 color-euclidean distance < / em>并最终挑选出每个滑动窗口的最大距离。因此,对于具有3x3
元素的9
窗口,您将拥有36
个唯一对。如果图片大小为MxN
,由于滑动性质,您会(M-3+1)*(N-3+1)
= 64516
(对于256x256
个案例)这样的滑动窗口,每个都有36对,因此距离数组的大小为36x64516
,最大距离的输出数组的大小为254x254
。这里建议的实现涉及im2col
将滑动窗口元素提取为列,nchoosek
以形成对,最后执行这些对的三个通道之间的平方差的平方根,看起来像这样 -
K = 3; %// Kernel size
Rch = im2col(img(:,:,1),[K,K],'sliding')
Gch = im2col(img(:,:,2),[K,K],'sliding')
Bch = im2col(img(:,:,3),[K,K],'sliding')
[idx1,idx2] = find(bsxfun(@gt,(1:K^2)',1:K^2)); %//'
Rsqdiff = (Rch(idx2,:) - Rch(idx1,:)).^2
Gsqdiff = (Gch(idx2,:) - Gch(idx1,:)).^2
Bsqdiff = (Bch(idx2,:) - Bch(idx1,:)).^2
dists = sqrt(Rsqdiff + Gsqdiff + Bsqdiff)
out = reshape(max(dists,[],1),size(img,1)-K+1,[])
答案 1 :(得分:2)
你的问题很有趣,引起了我的注意。据我所知,你需要计算3x3内核中所有单元格的RGB颜色值之间的欧氏距离,并找到最大的一个。我建议使用T(n) = 3*T(n*2/3)
函数和4D数组操作来实现此目的:
首先,我们填充输入数组并为每个方向创建8个移位版本:
circshift
接下来,我们创建一个数组,计算所有上述数组之间所有可能组合的差异:
DIM = 256;
A = zeros(DIM,DIM,3,9);
A(:,:,:,1) = round(255*rand(DIM,DIM,3));%// random 256x256 array (suppose it is your image)
A = padarray(A,[1,1]);%// add zeros on each side of image
%// compute shifted versions of the input array
%// and write them as 4th dimension starting from shifted up clockwise:
A(:,:,:,2) = circshift(A(:,:,:,1),[-1, 0]);
A(:,:,:,3) = circshift(A(:,:,:,1),[-1, 1]);
A(:,:,:,4) = circshift(A(:,:,:,1),[ 0, 1]);
A(:,:,:,5) = circshift(A(:,:,:,1),[ 1, 1]);
A(:,:,:,6) = circshift(A(:,:,:,1),[ 1, 0]);
A(:,:,:,7) = circshift(A(:,:,:,1),[ 1,-1]);
A(:,:,:,8) = circshift(A(:,:,:,1),[ 0,-1]);
A(:,:,:,9) = circshift(A(:,:,:,1),[-1,-1]);
最后,我们所拥有的是3x3内核中所有可能对之间的所有欧氏距离。我们所要做的就是提取最大值。据我所知,你不考虑图像边缘,所以:
q = nchoosek(1:9,2);
B = zeros(DIM+2,DIM+2,3,size(q,1));
for i = 1:size(q,1)
B(:,:,:,i) = (A(:,:,:,q(i,1)) - A(:,:,:,q(i,2))).^2;
end
C = sqrt(sum(B,3));
C = sqrt(sum(B,3));
D = zeros(DIM-2);
for i = 3:DIM
for j = 3:DIM
temp = C(i-1:i+1,j-1:j+1);
D(i-2,j-2) = max(temp(:));
end
end
是254x254阵列,A(2:255,2:255)的欧几里德距离最大,即我们排除图像边缘。
希望有所帮助。
P.S。我很惊讶@Divakar提供的代码很短。