4
\$\begingroup\$

The function im2col in MATLAB is very useful to vectorize Patch based Image Processing algorithms. The problem is the function isn't optimized and doesn't use C Code. I'm trying to build efficient C code for that.

This is the code I created:

function [ mColumnImage ] = ImageToColumns( mInputImage, blockRadius )
% ----------------------------------------------------------------------------------------------- %
% [ mColumnImage ] = ImageToColumns( mInputImage, blockRadius )
% Creates an column image from the sliding neighborhood in mInpuImage
% Input:
% - mInputImage - Input image.
% Matrix, 1 Channels, Floating Point
% - blockRadius - Local Window Radius.
% Scalar, Floating Point, {1, 2, ..., inf}.
% Output:
% - mColumnImage - Input image.
% Matrix, 1 Channels, Floating Point, [0, 1]
% Remarks:
% 1. Prefixes:
% - 'm' - Matrix.
% - 'v' - Vector.
% 2. C
% TODO:
% 1. I
% Release Notes:
% - 1.0.000 22/08/2014 R
% * First release version.
% ----------------------------------------------------------------------------------------------- %
numRows = size(mInputImage, 1);
numCols = size(mInputImage, 2);
blockSize = (2 * blockRadius) + 1;
numPixelsToProcess = (numRows - blockSize + 1) * (numCols - blockSize + 1);
mColumnImage = zeros((blockSize * blockSize), numPixelsToProcess);
colImageColIdx = 0;
for iColIdx = (blockRadius + 1):(numCols - blockRadius)
 for jRowIdx = (blockRadius + 1):(numRows - blockRadius)
 colImageColIdx = colImageColIdx + 1;
 colImageRowIdx = 0;
 for kPixelColIdx = -blockRadius:blockRadius
 for lPixelRowIdx = -blockRadius:blockRadius
 colImageRowIdx = colImageRowIdx + 1;
 mColumnImage(colImageRowIdx, colImageColIdx) = mInputImage((jRowIdx + lPixelRowIdx), (iColIdx + kPixelColIdx));
 end
 end
 end
end
end

It is MATLAB code written in C style. Imagine it was C code: what would you do make it faster? What would you do to allow compiler optimizations (loop unrolling, vectorization, parallelization, etc...)?

I posted vanilla C code I created and have a few questions about it:

  1. How can I make the memory access more efficient (hence make the code faster)?
  2. Any place to utilize vectorization?
  3. How can I assist the compiler and tell it no aliasing will happen?
  4. What would be the right way to utilize OpenMP?
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Aug 29, 2014 at 12:05
\$\endgroup\$
2
  • \$\begingroup\$ @CrisLuengo, The reason the inner loop are on the rows is because MATLAB is Column Major. \$\endgroup\$ Commented Feb 10, 2018 at 21:12
  • \$\begingroup\$ Sorry, I must have had a brain fart when I wrote that. \$\endgroup\$ Commented Feb 10, 2018 at 21:44

1 Answer 1

2
\$\begingroup\$

This is a valid C code which implements the above:

void ImageToColumns(float* mO, float* mI, int numRows, int numCols, int blockRadius)
{
 int blockSize, blockNumElements, colImageColIdx, colImageRowIdx;
 int ii, jj, kk, ll;
 blockSize = (2 * blockRadius) + 1;
 blockNumElements = blockSize * blockSize;
 colImageRowIdx = -1;
 for (ii = blockRadius; ii < (numRows - blockRadius); ii++)
 {
 for (jj = blockRadius; jj < (numCols - blockRadius); jj++)
 {
 colImageRowIdx = colImageRowIdx + 1;
 colImageColIdx = -1;
 for (kk = -blockRadius; kk <= blockRadius; kk++)
 {
 for (ll = -blockRadius; ll <= blockRadius; ll++)
 {
 colImageColIdx = colImageColIdx + 1;
 mO[(colImageRowIdx * blockNumElements) + colImageColIdx] = mI[((ii + kk) * numCols) + jj + ll];
 }
 }
 }
 }
}

Clearly this a memory bounded algorithm.

answered Aug 8, 2017 at 5:12
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.