matlabimage-processingmatrixtexturesmodulation

How to create diagonal stripe patterns and checkerboard patterns?


Based on this question, I can confirm that horizontal patterns can be imposed onto a matrix (which in this case is an image), by multiplying it with a modulation signal created with this:

vModulationSignal = 1 + (0.5 * cos(2 * pi * (signalFreq / numRows) * [0:(numRows - 1)].'));

It would also be great if someone could explain to why the above modulation signal works.

Now I want to create diagonal patterns such as :

enter image description here

And criss-cross (checkered) patterns such as this:

enter image description here

using a similar vModulationSignal


Code Excerpt where the modulation signal is created

numRows = size(mInputImage, 1);
numCols = size(mInputImage, 2);

signalFreq = floor(numRows / 1.25);

vModulationSignal = 1 + (0.5 * cos(2 * pi * (signalFreq / numRows) * [0:(numRows - 1)].'));

mOutputImage = bsxfun(@times, mInputImage, vModulationSignal);

Code Excerpt where I'm trying to create the criss cross signal

numRows = size(mInputImage, 1);
numCols = size(mInputImage, 2);

signalFreq1 = floor(numRows / 1.25);
signalFreq2 = floor(numCols / 1.25);

vModulationSignal1 = 1 + (0.5 * cos(2 * pi * (signalFreq / numRows) * [0:(numRows - 1)].'));

vModulationSignal2 = 1 + (0.5 * cos(2 * pi * (signalFreq / numRows) * [0:(numRows - 1)].'));

mOutputImage = bsxfun(@times, mInputImage, vModulationSignal);

figure();
imshow(mOutputImage);

Solution

  • For horizontal, vertical, diagonal stripes:

    fx = 1 / 20; % 1 / period in x direction
    fy = 1 / 20; % 1 / period in y direction
    Nx = 200; % image dimension in x direction
    Ny = 200; % image dimension in y direction
    [xi, yi] = ndgrid(1 : Nx, 1 : Ny);
    mask = sin(2 * pi * (fx * xi  + fy * yi)) > 0; % for binary mask
    mask = (sin(2 * pi * (fx * xi  + fy * yi)) + 1) / 2; % for gradual [0,1] mask
    imagesc(mask); % only if you want to see it
    

    just choose fx and fy accordingly (set fy=0 for horizontal stripes, fx=0 for vertical stripes and fx,fy equal for diagonal stripes). Btw. the period of the stripes (in pixels) is exactly

    period_in_pixel = 1 / sqrt(fx^2 + fy^2);
    

    For checkerboard patterns:

    f = 1 / 20; % 1 / period
    Nx = 200;
    Ny = 200;
    [xi, yi] = ndgrid(1 : Nx, 1 : Ny);
    mask = sin(2 * pi * f * xi) .* sin(2 * pi * f * yi) > 0; % for binary mask
    mask = (sin(2 * pi * f * xi) .* sin(2 * pi * f * yi) + 1) / 2; % for more gradual mask
    imagesc(mask);
    

    Here the number of black and white squares per x, y direction is:

    number_squares_x = 2 * f * Nx
    number_squares_y = 2 * f * Ny
    

    And if you know the size of your image and the number of squares that you want, you can use this to calculate the parameter f.

    Multiplying the mask with the image:

    Now that is easy. The mask is a logical (white = true, black = false). Now you only have to decide which part you want to keep (the white or the black part).

    Multiply your image with the mask

    masked_image = original_image .* mask;
    

    to keep the white areas in the mask and

    masked_image = original_image .* ~mask;
    

    for the opposite.