С реализацией обработки изображений с расширением создания повторяющихся узоров на результирующем изображении - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь реализовать операцию расширения с использованием C. Вот код, который я сделал

#include <stdio.h>
#include <stdlib.h>
#include "image.h"

#define IMG_ROWS 1280
#define IMG_COLS 1024
#define KERNEL_DIM 5 //kernel size

unsigned char imgIn[IMG_ROWS][IMG_COLS]; //grayscale values array
unsigned char imgOut[IMG_ROWS][IMG_COLS];

//Kernel initialization
int kernel[KERNEL_DIM][KERNEL_DIM] = {
        {1,1,1,1,1},
        {1,1,1,1,1},
        {1,1,1,1,1},
        {1,1,1,1,1},
        {1,1,1,1,1}
};

int main()
{

    //fill the img matrix
    for(int idxRow = 0; idxRow < IMG_ROWS; idxRow++){
        for(int idxCol = 0; idxCol < IMG_COLS; idxCol++){
            imgIn[idxRow][idxCol] = img[idxRow*IMG_COLS + idxCol];
            imgOut[idxRow][idxCol] = 0;
        }
    }

    int max;
    int offset = KERNEL_DIM/2;
    //Iterates over the image ignoring the borders
    for(int idxRow = offset; idxRow < IMG_ROWS - offset; idxRow++){
        for(int idxCol = offset; idxCol < IMG_COLS - offset; idxCol++){
            max = 0;
            //Iterates over the kernel
            for(int krnRow = -offset; krnRow < offset + 1; krnRow++){
                for(int krnCol = -offset; krnCol < offset + 1; krnCol++){
                    //Max value under the kernel
                    if(kernel[offset + krnRow][offset + krnCol]*
                            imgIn[idxRow + krnRow][idxCol + krnCol] > max)        {
                        max = imgIn[idxRow + krnRow][idxCol + krnCol];
                    }
                }
            }

            imgOut[idxRow][idxCol] = max;
        }
    }

    FILE *fp = fopen("ps_dil.log", "w");

    for(int idxRow = 0; idxRow < IMG_ROWS; idxRow++){
        for(int idxCol = 0; idxCol < IMG_COLS; idxCol++){
            fprintf(fp, "%d ", imgOut[idxRow][idxCol]);
        }
    }

    fclose(fp);

    return 0;

}

Как видите, мое входное изображение находится в массиве imgIn, а мой структурирующий элементнаходится в массиве kernel, где все элементы установлены в 1. Кроме того, я не обрабатываю границы, сохраняя его пиксели со значением 0.

Входное изображение поступает из одномерного массива,генерируется с помощью следующего сценария matlab:

function saveAsCArray( I )
[nRows, nCols] = size(I);

cFile = fopen('image.h', 'w');
fprintf(cFile, 'unsigned char img[%d] = {', (nRows*nCols));

for row = 1:nRows
    for col = 1:nCols
        if row == nRows && col == nCols
            fprintf(cFile, '%d};', I(row, col));
        else
            fprintf(cFile, '%d,', I(row, col));
        end
    end
    fprintf(cFile, '\n');
end

fclose(cFile);

end

Выходной файл журнала преобразуется обратно в изображение с помощью следующего сценария:

function intFileToImg( fileName, imgName, imgSizeRow, imgSizeCol)

    A = dlmread(fileName);
    A = uint8(A);
    A = reshape(A, imgSizeRow, imgSizeCol);
    A = rot90(A,3);
    I = mat2gray(A);
    I = flip(I, 2);
    imwrite(I, imgName);
    imshow(I);

end

Я реализовалрасширение таким образом, что выходной пиксель получает значение максимального пикселя внутри окна ядра.Проблема в том, что мое выходное изображение показывает некоторые странные повторения, которые, я думаю, связаны с ошибкой индексации.К сожалению, я не могу понять, что я делаю неправильно.

Вот мой ввод:

enter image description here

Вот мой вывод сЯдро 5x5: enter image description here

Вот мой вывод с ядром 3x3: enter image description here

Пожалуйста, кто-нибудь может взглянуть накод и помочь мне узнать, что я делаю не так?

1 Ответ

0 голосов
/ 08 февраля 2019

При преобразовании изображения в линейный массив вы пишете каждую строку последовательно (главная строка).Но затем при преобразовании линейного массива обратно в изображение вы используете следующую последовательность:

A = reshape(A, imgSizeRow, imgSizeCol);
A = rot90(A,3);
I = mat2gray(A);
I = flip(I, 2);

MATLAB является главным столбцом, поэтому вам понадобился rot90 там.Но из-за этого вам также следует переключить размеры строк и столбцов:

A = reshape(A, imgSizeCol, imgSizeRow).';
I = mat2gray(A);

Обратите также внимание, что rot90 + flip - это то же самое, что и транспонирование матрицы, а это то, что вам действительно нужноот основной матрицы строки до основной столбца вам нужно поменять местами два измерения, что и делает транспонирование).


Вы также должны исправить эти две строки кода в вашей C-программе:

#define IMG_ROWS 1280
#define IMG_COLS 1024

Изображение, опубликованное вами в качестве входных данных, содержит 502 строки и 622 столбца.

Я создал этот скрипт MATLAB:

% Load image
I = imread('https://i.stack.imgur.com/0u3bK.png');
I = I(:,:,1); % Keep only the first channel

% Write image
[nRows, nCols] = size(I);
cFile = fopen('image.h', 'w');
fprintf(cFile, '#define IMG_ROWS %d\n', nRows);
fprintf(cFile, '#define IMG_COLS %d\n', nCols);
fprintf(cFile, 'unsigned char img[%d] = {', (nRows*nCols));
fprintf(cFile, '%d,', I.'); % Note transpose!
fprintf(cFile, '};\n');
fclose(cFile);

% Compile & run C code
!gcc so.c -o so
!./so

% Load output
A = dlmread('ps_dil.log');
A = uint8(A);
A = reshape(A, nCols, nRows).';
imshow(A);

Файл so.cэто код C, который вы опубликовали, но с двумя удаленными строками, определяющими IMG_ROWS и IMG_COLS.Файл image.h, который я создаю здесь, записывает эти две строки.Это вывод, идеально мелкое расширение:

output of code above

...