Block Processing without Builtin blockproc
5 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hi,
I'm trying to build the blocproc as an algorithm to understand how it works.
I'm sliding a 3x3 window over the image, and applying the kernel to that block, then, moving to the next block.
I have this so far, it's not writing anything to the array with the for loop. Can someone take a look and see what I'm missing?
Thanks in advance.
img1 = 'cman.tif';
%read image in workspace
img1 = imread(img1);
imshow(img1)
kernel = .0625 * [1 2 1; 2 4 2; 1 2 1];
%%%%%%%%%%%%%%%%%%%
m = 3;
n = 3; %this is the 3x3 block that will iterate over image
img_temp = [];
[num_rows num_columns depth] = size(img1);
col_win_counter = 0;
for col = 1:n:num_cols
col_win_counter = col_win_counter +1;
row_win_counter = 0;
col_start = col;
col_stop = min(col+n-1,num_cols);
for row = 1:m:num_rows
row_win_counter = row_win_counter +1;
window = zeros(m,n);
row_start = row;
row_stop = min(row+m-1, num_rows);
window(1:row_stop-row_start+1,1:col_stop-col_start + 1) = ...
img1(row_start:row_stop, col_start:col_stop);
img_temp = mtimes(window, kernel);
end
end
spatial_img = num2cell(img_temp);
imshow(spatial_img);
6 commentaires
J. Alex Lee
le 7 Oct 2022
You are trying to fit a matrix of size 3x3 into an array of size 1x1, and it's also unclear whether you actually want that matrix times (*) vs element-wise times (.*).
If you actually meant element-wise, and you want to save the result into the original 3x3 slot of your image (and treat the edges specially when you don't have the full neighborhood), that's a convolution.
If you wanted to somehow collapse your 3x3 neighborhood into some single scalar and insert it into img_tmp at your counter location, that looks more like a block proc. However, what is the operation you actually want to do to collapse your 3x3 neighborhood into a scalar.
Réponses (1)
Image Analyst
le 27 Oct 2023
Looks like the other (chatbot) answer didn't get it fully correct.
You need to do the multiplication the correct way and then sum the result. Plus, you reversed the order of the row and column indexes in img_temp for some reason -- row goes first, not column. Additionally you should preallocate your output image otherwise it does it for every single pixel as you assign a new location and it will take a lot longer.
Corrected code is below:
% Demo by Image Analyst manually block process a gray scale image to downsample it.
% Modified version of what the user posted on Answers (not how I'd do it).
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format short g;
format compact;
fontSize = 22;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
originalImage = 'cameraman.tif';
% Read image from disk.
originalImage = imread(originalImage);
subplot(1, 2, 1);
imshow(originalImage)
axis('on', 'image');
title('Original image')
impixelinfo; % Let user mouse around and see location and gray level.
kernel = .0625 * [1 2 1; 2 4 2; 1 2 1]; % Will blur the image
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
myWindowHeight = 3;
nxWindowWidth = 3; %this is the 3x3 block that will iterate over image
[num_rows, num_columns, depth] = size(originalImage);
outputRows = floor(num_rows / myWindowHeight)
outputColumns = floor(num_columns / nxWindowWidth)
% Preallocate the output image.
outputImage = zeros(outputRows, outputColumns);
col_win_counter = 0;
for col = 1 : nxWindowWidth : num_columns
fprintf('Processing Row #%d of %d.\n', col, num_columns)
col_win_counter = col_win_counter +1;
row_win_counter = 0;
% Get starting and stopping columns of the current pixel location.
col_start = col;
col_stop = min(col+nxWindowWidth-1, num_columns); %stops before edge
% Go down all rows in this column summing the values in the local window.
for row = 1 : myWindowHeight : num_rows
row_win_counter = row_win_counter +1;
% Get starting and stopping rows of the current pixel location.
row_start = row;
row_stop = min(row+myWindowHeight-1, num_rows);
% Extract the local 3x3 window below and to the right of the current pixel.
thisLocalWindow = double(originalImage(row_start:row_stop, col_start:col_stop));
outputImage(row_win_counter, col_win_counter) = sum(thisLocalWindow .* kernel, 'all');
end
end
% Display floating point result image.
subplot(1, 2, 2);
imshow(outputImage, [])
axis('on', 'image');
impixelinfo; % Let user mouse around and see location and gray level.
title('Block processed image')
fprintf('Done with script.\n')
0 commentaires
Voir également
Catégories
En savoir plus sur Read, Write, and Modify Image dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!