我正在尝试使用C实现膨胀操作。这是我完成的代码
#include
#include
#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
for(int idxCol = 0; 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
for(int idxCol = 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
for(int idxCol = 0; 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, '\');
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
我以输出像素接收内核窗口内最大像素值的方式实现了扩展。问题是我的输出图像显示了一些奇怪的重复,我真的认为这与某些索引错误有关。不幸的是,我无法弄清楚我在做什么错。
这是我的输入:
这是我使用5x5内核的输出:
这是我使用3x3内核的输出:
请,有人可以看一下代码并帮助我找出我做错了什么吗?
您的内核行和列可能不是从-offset开始,而是在for(int krnRow = -offset和下一行开始的行中的0处。
(1)仅当kernel仅包含0和1值时,这才是有效的扩展。对于非二进制内核,您需要添加映像和内核值。 (2)您的结果确实看起来像是索引问题。不幸的是,我们无法告诉您出了什么问题,因为您没有提供一个可重复的示例。我们需要查看如何定义imgIn和imgOut,以了解索引出错的地方。您可能会混淆图像的宽度和高度。
@MarkSetchell我这样做了,所以我对像素邻居的索引会更容易。
@CrisLuengo我的内核仅包含0和1值,对不起,省略了此信息。此外,还编辑了帖子,添加了输入和输出图像的初始化。我的输入来自一维数组,其中包含像素的灰度值,我的输出图像用零初始化。
我真的认为初始化可以。我猜问题出在if或内核循环中。当我用if代替max = imgIn [idxRow] [idxCol]时,imgOut看起来与imgIn相同。
尝试更改为imgOut[..][..] = idxRow,然后尝试imgOut[..][..] = idxCol。
香港专业教育学院尝试的建议,都给了我正确的结果。 idxRow和idxCol看起来还不错,而且imgIn [idxRow] [idxCol + 1]也按预期返回了移位后的图像。我打印了* idxRow +偏移量和idxCol +偏移量以验证其值,我认为它们也可以。刚刚用完整的代码编辑了我的帖子。我仍然猜错是在内核循环内。但无法找到...
用256x256图片进行了测试。给我一个正确的结果。但是我没有任何想法,为什么用1280x1024的大图像无法正常工作。
仅提供更多信息:当我尝试使用3x3内核时,问题仍然存在,但有3次重复出现。将图片放在我的主要帖子中。
这种转变有效,取决于我添加到索引中的数量,我认为这是正常行为。此外,该程序还可以处理210 x 240的图像。关于我的输入和输出,我通过这种方式将代码放入我们在大学中使用的硬件中,那里的输入和输出系统尚未完成。但是首先我需要在PC上对其进行测试。我在matlab中做了一个scritp,它读取图像并从中生成未签名的char数组,另一个脚本读取该日志文件并生成图像。将在问题上添加他们的代码。
谢谢!现在完成了,我可以看到问题所在了。
将图像转换为线性数组时,可以连续写入每一行(主要行)。但是,当将线性数组转换回图像时,请使用以下序列:
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\', nRows);
fprintf(cFile, '#define IMG_COLS %d\', nCols);
fprintf(cFile, 'unsigned char img[%d] = {', (nRows*nCols));
fprintf(cFile, '%d,', I.'); % Note transpose!
fprintf(cFile, '};\
');
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文件写了这两行。这是输出,完美的扩展:
嗨,尝试修改我的matlab脚本,但是我仍然得到错误的结果。 我要做的是删除rot90和flip,并用A = reshape(A, imgSizeCol, imgSizeRow).;替换了A = reshape(A, imgSizeRow, imgSizeCol);。 当我刚刚意识到它创建了一个双矩阵时,我也删除了mat2gray。