图像处理膨胀的C实现在结果图像上创建重复图案
C implementation of image processing dilation creating repeated patterns on the result image
我正在尝试使用 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);
结束
使用以下脚本将输出日志文件转换回图像:
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
我以输出像素接收内核中最大像素值的方式实现扩张 window。问题是我的输出图像显示了一些奇怪的重复,我真的认为这与某些索引错误有关。不幸的是我不知道我做错了什么。
这是我的输入:
这是我使用 5x5 内核的输出:
这是我使用 3x3 内核的输出:
拜托,有人可以看一下代码并帮助我找出我做错了什么吗?
将图像转换为线性数组时,您连续写入每一行(行优先)。但是当将线性阵列转换回图像时,您使用这个序列:
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
文件写了这两行。这是输出,完美的扩张:
我正在尝试使用 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);
结束
使用以下脚本将输出日志文件转换回图像:
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
我以输出像素接收内核中最大像素值的方式实现扩张 window。问题是我的输出图像显示了一些奇怪的重复,我真的认为这与某些索引错误有关。不幸的是我不知道我做错了什么。
这是我的输入:
这是我使用 5x5 内核的输出:
这是我使用 3x3 内核的输出:
拜托,有人可以看一下代码并帮助我找出我做错了什么吗?
将图像转换为线性数组时,您连续写入每一行(行优先)。但是当将线性阵列转换回图像时,您使用这个序列:
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
文件写了这两行。这是输出,完美的扩张: