高斯差分与高斯拉普拉斯相似,都是先经过高斯平滑,再做差分,但这两个过程可结合成一起。高斯差分算子如下:
取sigma1 = 0.2, sigma2 = 0.8,离散化则
【-0.1045 -0.2283 -0.1045
-0.2283 1.4960 -0.2283
-0.1045 -0.2283 -0.1045 】
取整,并使模板总和为0,则
【-2, -5, -2
-5, 28,-5
-2, -5, -2】
#include"cv.h"
#include "highgui.h"
void DOG(CvMat* gray, CvMat* edge);
int main()
{
IplImage *src = cvLoadImage("GragonGirl.jpg",1);
const int width = src->width;
const int height = src->height;
CvMat *gray = cvCreateMat(height, width, CV_8UC1);
cvCvtColor(src, gray, CV_BGR2GRAY);
CvMat *edge = cvCreateMat(height, width, CV_8UC1);
DOG(gray, edge);
cvShowImage("SRC", src);
cvShowImage("GRAY", gray);
cvShowImage("DOG", edge);
cvWaitKey(0);
cvCvtColor(gray, src, CV_GRAY2BGR);
cvSaveImage("GRAY.bmp", src);
cvCvtColor(edge, src, CV_GRAY2BGR);
cvSaveImage("EDGE.bmp", src);
cvReleaseMat(&gray);
cvReleaseMat(&edge);
return 0;
}
void DOG(CvMat* gray, CvMat* edge)
{
const int width = gray->width;
const int height = gray->height;
cvZero(edge);
CvMat* edgeTemp1 = cvCreateMat(height, width, CV_16SC1);
cvZero(edgeTemp1);
int Template1[9] = { -2, -5, -2,
-5, 28, -5,
-2, -5, -2};
for (int j = 1; j < height - 1; j ++)
{
int* edgeTemp1Data = (int*)(edgeTemp1->data.ptr + j * edgeTemp1->step);
uchar* edgeData = (uchar*)(edge->data.ptr + j * edge->step);
for (int i = 1; i < width - 1; i ++)
{
for (int k = 0; k < 3; k ++)
{
for (int l = 0; l < 3; l ++)
{
edgeTemp1Data[i] += Template1[3 * k + l] * ((uchar*)(gray->data.ptr + (j + k - 1) * gray->step))[i + l - 1];
if (abs(edgeTemp1Data[i]) > 255)
{
edgeData[i] = 255;
}
else
{
edgeData[i] = abs(edgeTemp1Data[i]);
}
}
}
}
}
cvReleaseMat(&edgeTemp1);
}
源图,灰度图,效果图如下所示