矩阵乘法问题 (java)
Trouble with matrix multiplication (java)
我正在处理卷积运算(特征图),我遇到了这个问题:
当我输入方形图像时,代码运行完美并且输出是图像转换后的图像(一切正常)
这是代码:
long ImageMatrix[][] = new long[width][height];
int CounterColumns = 0;
BufferedImage KernelImg = new BufferedImage(width-2,height-2,BufferedImage.TYPE_INT_ARGB);
try {
for (j = 0; j < height-2; j++) {
for (k = 0; k < width-2; k++) {
for (w = 0; w < 3; w++) {
for (v = 0; v < 3; v++) {
int Sj = j + w;
int Sv = v + CounterColumns;
sum += ImageMatrix[Sj][Sv] * Kernel[w][v];
}
}
int a = 255;
int p = (a << 24) | (sum << 16) | (sum << 8) | sum;
sum = 0;
CounterColumns++;
count++;
KernelImg.setRGB(j, k, p);
}
CounterColumns = 0;
}
}
catch(Exception e){
System.out.println(e);
}
上面的代码是核矩阵(3x3矩阵)和图像矩阵相乘的循环,这是核矩阵的一个例子:
int Kernel[][] = {
{-1,-1,-1},
{-1,8,-1},
{-1,-1,-1}
};
问题是,当我输入矩形图像时,系统停止工作并向我抛出此错误:
java.lang.ArrayIndexOutOfBoundsException: 165
我已经搜索过这个错误,但我没有找到任何解决问题的方法,而且我不知道为什么代码使用方形图像运行没有问题,但如果我输入矩形图像,就会出现错误。
谢谢你能帮我解决这个问题。
您的代码是不对称的:您处理列的方式与处理行的方式不同;就索引而言,它们都应该被同等对待:
try {
for (j = 0; j < width-2; j++) {
for (k = 0; k < height-2; k++) {
for (w = 0; w < 3; w++) {
for (v = 0; v < 3; v++) {
int Sj = j + w;
int Sv = k+v;
sum += ImageMatrix[Sj][Sv] * Kernel[w][v];
}
}
}
您还必须正确使用索引:j 范围在 0..width-2 和 k 在 0..height-2
你必须在你处理的像素上以内核为中心。这是灰度图像的基本示例:
BufferedImage source = // A TYPE_BYTE_GRAY image
BufferedImage result = new BufferedImage(source.getWidth(), source.getHeight(), BufferedImage.TYPE_BYTE_GRAY) ;
try {
for (int y=1 ; y < height-1 ; y++)
for (int x=0 ; x < width-1; x++)
{
int sum = 0 ;
for (int i=-1 ; i <= 1 ; i++)
for (int j=-1 ; j <= 1 ; j++)
sum += source.getRaster().getSample(x, y, 0) * Kernel[i+1][j+1] ;
result.getRaster().setSample(x, y, 0, sum) ;
}
}
catch (Exception e)
{
e.printStackTrace() ;
}
在渐变的情况下,边界操作没有明确定义(不同的解决方案,但 none 是一个很好的解决方案),所以在这个例子中你最终得到零。
我正在处理卷积运算(特征图),我遇到了这个问题:
当我输入方形图像时,代码运行完美并且输出是图像转换后的图像(一切正常)
这是代码:
long ImageMatrix[][] = new long[width][height];
int CounterColumns = 0;
BufferedImage KernelImg = new BufferedImage(width-2,height-2,BufferedImage.TYPE_INT_ARGB);
try {
for (j = 0; j < height-2; j++) {
for (k = 0; k < width-2; k++) {
for (w = 0; w < 3; w++) {
for (v = 0; v < 3; v++) {
int Sj = j + w;
int Sv = v + CounterColumns;
sum += ImageMatrix[Sj][Sv] * Kernel[w][v];
}
}
int a = 255;
int p = (a << 24) | (sum << 16) | (sum << 8) | sum;
sum = 0;
CounterColumns++;
count++;
KernelImg.setRGB(j, k, p);
}
CounterColumns = 0;
}
}
catch(Exception e){
System.out.println(e);
}
上面的代码是核矩阵(3x3矩阵)和图像矩阵相乘的循环,这是核矩阵的一个例子:
int Kernel[][] = {
{-1,-1,-1},
{-1,8,-1},
{-1,-1,-1}
};
问题是,当我输入矩形图像时,系统停止工作并向我抛出此错误:
java.lang.ArrayIndexOutOfBoundsException: 165
我已经搜索过这个错误,但我没有找到任何解决问题的方法,而且我不知道为什么代码使用方形图像运行没有问题,但如果我输入矩形图像,就会出现错误。
谢谢你能帮我解决这个问题。
您的代码是不对称的:您处理列的方式与处理行的方式不同;就索引而言,它们都应该被同等对待:
try {
for (j = 0; j < width-2; j++) {
for (k = 0; k < height-2; k++) {
for (w = 0; w < 3; w++) {
for (v = 0; v < 3; v++) {
int Sj = j + w;
int Sv = k+v;
sum += ImageMatrix[Sj][Sv] * Kernel[w][v];
}
}
}
您还必须正确使用索引:j 范围在 0..width-2 和 k 在 0..height-2
你必须在你处理的像素上以内核为中心。这是灰度图像的基本示例:
BufferedImage source = // A TYPE_BYTE_GRAY image
BufferedImage result = new BufferedImage(source.getWidth(), source.getHeight(), BufferedImage.TYPE_BYTE_GRAY) ;
try {
for (int y=1 ; y < height-1 ; y++)
for (int x=0 ; x < width-1; x++)
{
int sum = 0 ;
for (int i=-1 ; i <= 1 ; i++)
for (int j=-1 ; j <= 1 ; j++)
sum += source.getRaster().getSample(x, y, 0) * Kernel[i+1][j+1] ;
result.getRaster().setSample(x, y, 0, sum) ;
}
}
catch (Exception e)
{
e.printStackTrace() ;
}
在渐变的情况下,边界操作没有明确定义(不同的解决方案,但 none 是一个很好的解决方案),所以在这个例子中你最终得到零。