sobel算子与图像卷积
图像卷积
//图像的卷积运算
/*
* QImage *image 输入图像
* QImage &TemplateImg 输出图像
* int nTempH 模板的height = (nTempH -1)3x3的模板
* int nTempW 模板的width =(nTempW - 1) 3x3的模板
* int nTempMY,int nTempMX 模板中心点的位置
* float *pfArray 模板数组
* float fCorf 加权系数
*/
void MainWindow::Template(QImage *image,QImage &TemplateImg,int nTempH,int nTempW,int nTempMY,int nTempMX,float *pfArray,float fCorf)
{
QColor oldColor;
//扫描图像就行卷积运算
for(int i = nTempMY; i< (image->height() - (nTempH-nTempMY)) + 1; i++)
{
for(int j = nTempMX; j < (image->width() - (nTempW-nTempMX)) + 1; j++)
{
//i的中心点
float fResult = 0;
for(int k = 0; k < nTempH; k++)
{
for(int l = 0; l < nTempW; l++)
{
oldColor = QColor(image->pixel((j + l - nTempMX), (i + k - nTempMY)));
//计算累加和
fResult += oldColor.red() * pfArray[k * nTempW + 1];
}
}
//系数
fResult *= fCorf;
//去绝对值
fResult = (float)fabs(fResult);
BYTE byte;
if(fResult>255)
{
byte = 255;
}
else
{
byte = fResult + 0.5;
}
TemplateImg.setPixel(j,i, qRgb(byte, byte, byte));
}
}
}
sobel算子
/*
* QImage *image 输入图像
* QImage &SobelIma 输出图像
* int modle 0:为计算x y方向的梯度值 1:计算x方向的梯度 2:计算y方向的梯度 3:计算45度方向的梯度 4:计算135度方向的梯度
* bool pdouble 是否返回梯度的方向与梯度的幅值
*/
double* MainWindow::Sobel_gradiant(QImage *image,QImage &SobelIma,int modle,bool pdouble)
{
float sobel_y[9] = {-1,-2,-1,
0,0,0,
1,2,1
};
float sobel_x[9] = {-1,0,1,
-2,0,2,
-1,0,1
};
float sobel_135[9] = {0,1,2
-1,0,1,
-2,-1,0
};
float sobel_45[9] = {-2,-1,0,
-1,0,1,
0,1,2
};
int width = image->width();
//int height = image->height();
int allnum = image->width()*image->height();
double *arr_point_X = new double[allnum];
memset(arr_point_X,0,allnum * sizeof(double));
double *arr_point_Y = new double[allnum];
memset(arr_point_Y,0,allnum * sizeof(double));
double *angle = new double[allnum];
memset(angle,0,allnum * sizeof(double));
double *Amplitude = new double[allnum];
memset(Amplitude,0,allnum * sizeof(double));
QColor oldColor1,oldColor2,oldColor3,oldColor4,oldColor5,oldColor6;
QColor v_oldColor1,v_oldColor2,v_oldColor3,v_oldColor4,v_oldColor5,v_oldColor6;
//选择梯度模式
switch (modle) {
case 0:
double kerne1_Result,kerne2_Result,all_Result;
int result;
for(int j=1;jheight()-1;j++)
{
for(int i=1; iwidth()-1;i++)
{
//垂直梯度
oldColor1 = QColor(image->pixel(i-1,j-1));
oldColor2 = QColor(image->pixel(i,j-1));
oldColor3 = QColor(image->pixel(i+1,j-1));
oldColor4 = QColor(image->pixel(i-1,j+1));
oldColor5 = QColor(image->pixel(i,j+1));
oldColor6 = QColor(image->pixel(i+1,j+1));
kerne1_Result = (oldColor1.red()+oldColor2.red()*2+oldColor3.red())-(oldColor4.red()+oldColor5.red()*2+oldColor6.red());
//水平梯度
v_oldColor1 = QColor(image->pixel(i-1,j-1));
v_oldColor2 = QColor(image->pixel(i-1,j));
v_oldColor3 = QColor(image->pixel(i-1,j+1));
v_oldColor4 = QColor(image->pixel(i+1,j-1));
v_oldColor5 = QColor(image->pixel(i+1,j));
v_oldColor6 = QColor(image->pixel(i+1,j+1));
kerne2_Result = (v_oldColor1.red()+v_oldColor2.red()*2+v_oldColor3.red())-(v_oldColor4.red()+v_oldColor5.red()*2+v_oldColor6.red());
//all_Result = abs(kerne2_Result)+abs(kerne1_Result);
all_Result = sqrt((kerne2_Result*kerne2_Result)+(kerne1_Result*kerne1_Result));
//保存xy方向的梯度
arr_point_X[j*width + i] = kerne2_Result;
arr_point_Y[j*width + i] = kerne1_Result;
Amplitude[j*width + i] = all_Result;
angle[j*width + i] = atan2(kerne1_Result,kerne2_Result);
if(all_Result>255){
result = 255;
}else {
result = all_Result + 0.5;
}
SobelIma.setPixel(i,j, qRgb(result, result, result));
}
}
// this->Show_Image(SobelIma);
break;
case 1:
this->Template(image,SobelIma,3,3,1,1,sobel_x,1);
//this->Show_Image(SobelIma);
break;
case 2:
this->Template(image,SobelIma,3,3,1,1,sobel_y,1);
//this->Show_Image(SobelIma);
break;
case 3:
this->Template(image,SobelIma,3,3,1,1,sobel_45,1);
//this->Show_Image(SobelIma);
break;
case 4:
this->Template(image,SobelIma,3,3,1,1,sobel_135,1);
//this->Show_Image(SobelIma);
break;
default:
break;
}