如何从图像中删除所有黑色像素并仅使用图像中找到的唯一 RGB 值
How can I delete all black pixels from an image and only use the unique RGB values found in the image
如何从图像中删除所有黑色像素并仅使用在图像中找到的唯一 RGB 值
What I'm trying to do is:
1) delete all black pixels from the image and only use the unique RGB colors found in the image
2) export each combined RGB color pixels that is unique as a separate 640x480 image
3) Convert / join these images into a movie file.
我的想法是将我的红色、绿色和蓝色通道拆分为相应的颜色,并将它们重塑为三个数组,每个数组一列。
并开始删除黑色像素。
如何删除所有黑色单元格值(其中 R、G、B 通道为 0)并仅查找/使用唯一的 RGB 值
我附上了下面的图片和一段代码:
resize_tmp_red=reshape(fintersect_red',[1,1200*1200])(:); %will cause array to be created / reshaped left to right and top to bottom (like reading a book) into 1 column
resize_tmp_green=reshape(fintersect_green',[1,1200*1200])(:);
resize_tmp_blue=reshape(fintersect_blue',[1,1200*1200])(:);
%How can I delete all cell values that are black (where the R,G,B channels are 0) and only find / use the RGB values that are unique in the image
for cc=1:10
repmat_rgb(:,:,1)=uint8(repmat(resize_tmp_red(cc,1),[640,480])); %creates 640x480 image of RGB taken from deleted black and unique color array.
repmat_rgb(:,:,2)=uint8(repmat(resize_tmp_green(cc,1),[640,480]));
repmat_rgb(:,:,3)=uint8(repmat(resize_tmp_blue(cc,1),[640,480]));
%imshow(repmat_rgb)
imwrite(repmat_rgb,strcat('/tmp/',sprintf('%03d', cc),'_img.png')); %creates image file
end
PS:我使用的是 Octave 4.0,它类似于 Matlab。
是的,我将不再看到原始图像的结构。我将仅使用图像中的独特颜色制作电影。
我不使用你在代码中输入的语言,但如果我在 c/c++ 中这样做,我会遍历数据并计算非黑色像素,创建一个新的该大小的数组,然后再次循环并将它们一一复制到新数组中。这能做到吗?
我不确定这是否是最好的方法,但你可以这样做:
R = double(im(:,:,1))*255*255;
G = double(im(:,:,2))*255;
B = double(im(:,:,3));
RGB = R+G+B; % Now you have 2D matrix
unq = sort(unique(RGB));
unq = unq(2:end); %remove (0,0,0)
B2 = rem(unq(:),255);
G2 = rem((unq-B2)/255,255);
R2 = (unq-G2*255 - B2)/255/255;
% You can make this part more efficient probably. and make sure there is no error
colors_you_want = [R2 G2 B2];
我所做的是,我将 3D 图像转换为 2D 双矩阵并找到所有独特的元素,即您想要的所有颜色。 unq
的第一个元素是 (0,0,0),所以我删除了那个。然后我转换回二维结构,其中 R 是第一列,G 是第二列,B 是第三列。
要找到黑色像素,您只需让所有三个颜色通道都为零即可。您可以告诉 sum
函数对第三个维度求和。如果三个通道都为零,则总和也为零。
im = imread('example.png');
black_mask = sum(im, 3) == 0;
现在你有一个指示黑色像素的二维蒙版。下一步是构建掩码以访问每个通道中的所有其他像素
red_mask = ~cat(3, black_mask, ones(size(black_mask)), ones(size(black_mask)))); %The inverse of the black mask in the red channel and any pixel in all other channels
green_mask = ~cat(3, ones(size(black_mask)), black_mask, ones(size(black_mask))));%For the other channels just change the order.
blue_mask= ~cat(3, ones(size(black_mask)), ones(size(black_mask)), black_mask));
好的,现在我们可以从每个通道中获取值了。
red = im(red_mask);
blue = im(blue_mask);
green = im(green_mask);
并在三维中将它们连接起来制作图像
non_unique = cat(3, red, green, blue);
non_unique
是包含所有非黑色像素的图像。要获得唯一像素,您必须置换矩阵以使用 unique
的 'row' 选项。
non_unique = permute(non_unique, [1 3 2]);
output = unique(non_unique, 'rows'); %Get unique rows
output = permute(output, [1 3 2]); %Permute it back to recover color channels
输出图像为 1 像素宽和 94 像素长。要获得所需的 640x480 形状,您需要对其进行整形和调整大小。我找不到任何好的因子来获得所需的比率,所以我只使用了 94: 2 和 47 这两个最大的素因子。
reshaped_output = reshape(output, 2, 47, 3);
reshaped_output = imresize(reshaped_output, [480, 640]);
这是图像在各个步骤的比较。
正如您在评论中提到的,您想要一个具有独特颜色的输出二维矩阵,其中每一行都是一个 RGB 元组 没有 黑色像素。您可以做的是将 RGB 图像重塑为 2D 矩阵,其中每一列都是一个颜色通道,删除行完全为 0 的所有实例,然后 运行 通过 unique
to remove the duplicates. To do this, you will need to perform a per channel transpose by using permute
, then exploiting the order of the elements with reshape
to finally create a 3 column matrix of RGB values. Once you do this, use any
找到所有具有至少一个值(即不是黑色像素),过滤掉矩阵中完全为零的行,然后最后使用 unique
但将其应用于行,以便每一行都被视为一个 "example" ,假设您的图像存储在 im
:
像这样的东西会起作用:
% Reshape the RGB image into a 3 column matrix
R = reshape(permute(im, [2 1 3]), [], 3);
% Remove black pixels
R = R(any(R, 2), :);
% Remove duplicates
colours = unique(R, 'rows', 'stable');
colours
将是没有黑色的唯一颜色输出二维矩阵。请注意,我使用 'stable'
标志来维护遇到颜色的顺序。通过省略它,它将按输出中的行 sort 矩阵。正如您在评论中指出的那样,Octave 不支持此功能,因此如果您不关心订单,您可以删除 'stable'
标志,我相信在这种情况下您不需要,因为您只想要一个矩阵不包括黑色的独特颜色。
因此:
colours = unique(R, 'rows');
如何从图像中删除所有黑色像素并仅使用在图像中找到的唯一 RGB 值
What I'm trying to do is:
1) delete all black pixels from the image and only use the unique RGB colors found in the image
2) export each combined RGB color pixels that is unique as a separate 640x480 image
3) Convert / join these images into a movie file.
我的想法是将我的红色、绿色和蓝色通道拆分为相应的颜色,并将它们重塑为三个数组,每个数组一列。 并开始删除黑色像素。
如何删除所有黑色单元格值(其中 R、G、B 通道为 0)并仅查找/使用唯一的 RGB 值
我附上了下面的图片和一段代码:
resize_tmp_red=reshape(fintersect_red',[1,1200*1200])(:); %will cause array to be created / reshaped left to right and top to bottom (like reading a book) into 1 column
resize_tmp_green=reshape(fintersect_green',[1,1200*1200])(:);
resize_tmp_blue=reshape(fintersect_blue',[1,1200*1200])(:);
%How can I delete all cell values that are black (where the R,G,B channels are 0) and only find / use the RGB values that are unique in the image
for cc=1:10
repmat_rgb(:,:,1)=uint8(repmat(resize_tmp_red(cc,1),[640,480])); %creates 640x480 image of RGB taken from deleted black and unique color array.
repmat_rgb(:,:,2)=uint8(repmat(resize_tmp_green(cc,1),[640,480]));
repmat_rgb(:,:,3)=uint8(repmat(resize_tmp_blue(cc,1),[640,480]));
%imshow(repmat_rgb)
imwrite(repmat_rgb,strcat('/tmp/',sprintf('%03d', cc),'_img.png')); %creates image file
end
PS:我使用的是 Octave 4.0,它类似于 Matlab。 是的,我将不再看到原始图像的结构。我将仅使用图像中的独特颜色制作电影。
我不使用你在代码中输入的语言,但如果我在 c/c++ 中这样做,我会遍历数据并计算非黑色像素,创建一个新的该大小的数组,然后再次循环并将它们一一复制到新数组中。这能做到吗?
我不确定这是否是最好的方法,但你可以这样做:
R = double(im(:,:,1))*255*255;
G = double(im(:,:,2))*255;
B = double(im(:,:,3));
RGB = R+G+B; % Now you have 2D matrix
unq = sort(unique(RGB));
unq = unq(2:end); %remove (0,0,0)
B2 = rem(unq(:),255);
G2 = rem((unq-B2)/255,255);
R2 = (unq-G2*255 - B2)/255/255;
% You can make this part more efficient probably. and make sure there is no error
colors_you_want = [R2 G2 B2];
我所做的是,我将 3D 图像转换为 2D 双矩阵并找到所有独特的元素,即您想要的所有颜色。 unq
的第一个元素是 (0,0,0),所以我删除了那个。然后我转换回二维结构,其中 R 是第一列,G 是第二列,B 是第三列。
要找到黑色像素,您只需让所有三个颜色通道都为零即可。您可以告诉 sum
函数对第三个维度求和。如果三个通道都为零,则总和也为零。
im = imread('example.png');
black_mask = sum(im, 3) == 0;
现在你有一个指示黑色像素的二维蒙版。下一步是构建掩码以访问每个通道中的所有其他像素
red_mask = ~cat(3, black_mask, ones(size(black_mask)), ones(size(black_mask)))); %The inverse of the black mask in the red channel and any pixel in all other channels
green_mask = ~cat(3, ones(size(black_mask)), black_mask, ones(size(black_mask))));%For the other channels just change the order.
blue_mask= ~cat(3, ones(size(black_mask)), ones(size(black_mask)), black_mask));
好的,现在我们可以从每个通道中获取值了。
red = im(red_mask);
blue = im(blue_mask);
green = im(green_mask);
并在三维中将它们连接起来制作图像
non_unique = cat(3, red, green, blue);
non_unique
是包含所有非黑色像素的图像。要获得唯一像素,您必须置换矩阵以使用 unique
的 'row' 选项。
non_unique = permute(non_unique, [1 3 2]);
output = unique(non_unique, 'rows'); %Get unique rows
output = permute(output, [1 3 2]); %Permute it back to recover color channels
输出图像为 1 像素宽和 94 像素长。要获得所需的 640x480 形状,您需要对其进行整形和调整大小。我找不到任何好的因子来获得所需的比率,所以我只使用了 94: 2 和 47 这两个最大的素因子。
reshaped_output = reshape(output, 2, 47, 3);
reshaped_output = imresize(reshaped_output, [480, 640]);
这是图像在各个步骤的比较。
正如您在评论中提到的,您想要一个具有独特颜色的输出二维矩阵,其中每一行都是一个 RGB 元组 没有 黑色像素。您可以做的是将 RGB 图像重塑为 2D 矩阵,其中每一列都是一个颜色通道,删除行完全为 0 的所有实例,然后 运行 通过 unique
to remove the duplicates. To do this, you will need to perform a per channel transpose by using permute
, then exploiting the order of the elements with reshape
to finally create a 3 column matrix of RGB values. Once you do this, use any
找到所有具有至少一个值(即不是黑色像素),过滤掉矩阵中完全为零的行,然后最后使用 unique
但将其应用于行,以便每一行都被视为一个 "example" ,假设您的图像存储在 im
:
像这样的东西会起作用:
% Reshape the RGB image into a 3 column matrix
R = reshape(permute(im, [2 1 3]), [], 3);
% Remove black pixels
R = R(any(R, 2), :);
% Remove duplicates
colours = unique(R, 'rows', 'stable');
colours
将是没有黑色的唯一颜色输出二维矩阵。请注意,我使用 'stable'
标志来维护遇到颜色的顺序。通过省略它,它将按输出中的行 sort 矩阵。正如您在评论中指出的那样,Octave 不支持此功能,因此如果您不关心订单,您可以删除 'stable'
标志,我相信在这种情况下您不需要,因为您只想要一个矩阵不包括黑色的独特颜色。
因此:
colours = unique(R, 'rows');