MATLAB [Matlab] Transform generated table to equation for for loop usage

AI Thread Summary
The discussion revolves around optimizing MATLAB code for processing a matrix A by replacing a lookup table with direct calculations. The user initially employed the im2col function to segment a binary image matrix into 3x3 raster segments, which resulted in a large memory footprint due to the creation of a location table for the center points of these segments. The goal is to map the center point of each raster segment directly to its corresponding location in matrix A without storing the entire location table.The user identifies that the row and column indices for the center point can be derived from the current row and column indices in the nested for loops. By incrementing these indices appropriately, the user can directly compute the location in A as [row + 1, col + 1], thus eliminating the need for the large location table. This approach not only reduces memory usage but also simplifies the code structure.
roldy
Messages
206
Reaction score
2
I have posted a question on here before regarding the generation of a number sequence. I followed up that question with an answer. However, as I have developed my code more I need to use an equation instead of a lookup table.

Note: I'm using MATLAB

Given a matrix A of size r x c where r >= 3, c >= 3 I need to map the center point of a 3 x 3 raster segment to a point in A. The raster segments go from left to right, top to bottom. For example, if

Code:
A = [0 1 1 0 1 0 1 0 1;...
      0 0 1 0 0 1 1 0 1;...
      1 0 1 1 0 1 0 1 0;...
      1 1 1 1 1 1 1 1 1];...

The location of (2,2) in each raster segment can be found as follows.

Code:
%raster binary image matrix into 3x3 segments
M = im2col(FP, [3,3],'sliding');

[ri ci] = size(A);
[rM cM] = size(M);

%Generate table of locations in binary image matrix for center point (2,2) of segment matrices
rownums = repmat([2:ri-1],cM/(ri-2),1);
rownums = rownums(:);

colnums = repmat([2:ci-1]',1,cM/(ci-2));
colnums = colnums(:);

locations = [rownums,colnums]

I only need matrix M to find what rM and cM are. Instead of using the im2col() function, I can use the equations below. cM is the number of total raster segments

Code:
rM = 9;
cM = (ci-2)*(ri-2);

I do some matrix operations for each raster segment using a for loop

Code:
n = 1;

k = 1; 
for row = 1:ri-2
 
	for col = 1:ci-2
  
           %some operations
                
                if %condition is met
                    %transform center point location in raster segment
                    %to corresponding location in matrix A
                    Iloc(n,:) = locations(k,:);
                    n = n+1; 
                end
            
            else   %if condition is not met, increment segment counter k and continue
                    %in for loop to next segment
                k = k+1;
                continue
            end
        k = k+1;
	end
	
end

I would like to replace this line of code
Code:
Iloc(n,:) = locations(k,:);
with equations for the row and column location in A instead of looking up in the table for these locations. The reason for this is that if I have a matrix A of size 274 x 234, I would have 63104 raster segments. This means that my location table matrix would be 63104 x 2. This takes up a lot of memory with the other stuff that I am doing. I know it's possible to come up with some equation that's dependent on the value of row, col, and k. It seems that every (ci-2) kth value, the row in A increments by one. For every different row value, the column values go from 2:(ci-1).
Question is how do I activate the row increment and column range for every (ci-2) kth value?
 
Physics news on Phys.org
My first reaction is that instead of summing over rows and columns you can probably vectorize the operation to save a lot of memory. Nested for loops are really expensive here, so it's worth looking in to.

Also, im2col() puts the 3x3 matrices in the columns of M, so that M(5,:) is the row vector of the (2,2) element in each 3x3 matrix.

Then

m = reshape(M(5,:),272,232)

turns that vector of centers into the same form as it is in A, and is equivalent to A with the edge values shaved off, A(2:end-1,2:end-1).

Each element in this matrix corresponds to the center of one of the 3x3 matrices, and the indices are each padded by 1, i.e. the (1,1) element in m is the (2,2) element in A, and so on.
 
kreil, within the nested for loops I submit the raster segment to a trained neural network to see if there is a match (part of the project criteria). The simulation of the neural network goes in place of "some operations". If I return a match, then I proceed to get the location from the table that's the if logic statement. Once I get all the locations, I use a logical mask to color a pixel red at transformed locations. There are two ways that I can go about this. The first method I tried was to just use one for loop that cycles through each raster segment in M. This is originally why I needed the table for the locations. The reason why I'm leaning towards the nested for loop is because I don't have to store anything, such as the huge M matrix or the table locations if I can transform the table calculations to equations. Any thoughts on this?

I've attached the necessary files to run this program. The main program is locateBifurcation. I've included a fingerprint image in case you wanted to test this on a full fingerprint instead of the small test logic matrix I created. The image must first get passed into imread() then into preprocess(I) to convert to a binary matrix.
 

Attachments

Last edited:
I think I figure this out. Simple solution actually, don't know why I didn't think of this before. I just replaced the table look up with the row and col value added by one from the for loops.
Code:
if %condition is met
   %transform center point location in raster segment
   %to corresponding location in matrix A
   Iloc(n,:) = [row+1,col+1];
   %Iloc(n,:) = locations(k,:);
   n = n+1; 
end
 
Back
Top