由8个卷积核组成Krisch边缘检测算子, 8个卷积核分别对图像卷积,取最大值点作为边缘点。
#include"cv.h"
#include "highgui.h"
void Krisch(CvMat* gray, CvMat* edge);
int main()
{
IplImage *src = cvLoadImage("flower.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);
Krisch(gray, edge);
cvShowImage("SRC", src);
cvShowImage("GRAY", gray);
cvShowImage("ROBERTS", 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 Krisch(CvMat* gray, CvMat* edge)
{
const int width = gray->width;
const int height = gray->height;
cvZero(edge);
CvMat* edgeTemp1 = cvCreateMat(height, width, CV_16SC1);
CvMat* edgeTemp2 = cvCreateMat(height, width, CV_16SC1);
CvMat* edgeTemp3 = cvCreateMat(height, width, CV_16SC1);
CvMat* edgeTemp4 = cvCreateMat(height, width, CV_16SC1);
CvMat* edgeTemp5 = cvCreateMat(height, width, CV_16SC1);
CvMat* edgeTemp6 = cvCreateMat(height, width, CV_16SC1);
CvMat* edgeTemp7 = cvCreateMat(height, width, CV_16SC1);
CvMat* edgeTemp8 = cvCreateMat(height, width, CV_16SC1);
cvZero(edgeTemp1);
cvZero(edgeTemp2);
cvZero(edgeTemp3);
cvZero(edgeTemp4);
cvZero(edgeTemp5);
cvZero(edgeTemp6);
cvZero(edgeTemp7);
cvZero(edgeTemp8);
int Template1[9] = { 5, 5, 5,
-3, 0, -3,
-3, -3, -3 };
int Template2[9] = { -3, 5, 5,
-3, 0, 5,
-3, -3, -3 };
int Template3[9] = { -3, -3, 5,
-3, 0, 5,
-3, -3, 5 };
int Template4[9] = { -3, -3, -3,
-3, 0, 5,
-3, 5, 5 };
int Template5[9] = { -3, -3, -3,
-3, 0, -3,
5, 5, 5 };
int Template6[9] = { -3, -3, -3,
5, 0, -3,
5, 5, -3 };
int Template7[9] = { 5, -3, -3,
5, 0, -3,
5, -3, -3 };
int Template8[9] = { 5, 5, -3,
5, 0, -3,
-3, -3, -3 };
for (int j = 1; j < height - 1; j ++)
{
int* edgeTemp1Data = (int*)(edgeTemp1->data.ptr + j * edgeTemp1->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];
}
}
}
}
for (int j = 1; j < height - 1; j ++)
{
int* edgeTemp2Data = (int*)(edgeTemp2->data.ptr + j * edgeTemp2->step);
for (int i = 1; i < width - 1; i ++)
{
for (int k = 0; k < 3; k ++)
{
for (int l = 0; l < 3; l ++)
{
edgeTemp2Data[i] += Template2[3 * k + l] * ((uchar*)(gray->data.ptr + (j + k - 1) * gray->step))[i + l - 1];
}
}
}
}
for (int j = 1; j < height - 1; j ++)
{
int* edgeTemp3Data = (int*)(edgeTemp3->data.ptr + j * edgeTemp3->step);
for (int i = 1; i < width - 1; i ++)
{
for (int k = 0; k < 3; k ++)
{
for (int l = 0; l < 3; l ++)
{
edgeTemp3Data[i] += Template3[3 * k + l] * ((uchar*)(gray->data.ptr + (j + k - 1) * gray->step))[i + l - 1];
}
}
}
}
for (int j = 1; j < height - 1; j ++)
{
int* edgeTemp4Data = (int*)(edgeTemp4->data.ptr + j * edgeTemp4->step);
for (int i = 1; i < width - 1; i ++)
{
for (int k = 0; k < 3; k ++)
{
for (int l = 0; l < 3; l ++)
{
edgeTemp4Data[i] += Template4[3 * k + l] * ((uchar*)(gray->data.ptr + (j + k - 1) * gray->step))[i + l - 1];
}
}
}
}
for (int j = 1; j < height - 1; j ++)
{
int* edgeTemp5Data = (int*)(edgeTemp5->data.ptr + j * edgeTemp5->step);
for (int i = 1; i < width - 1; i ++)
{
for (int k = 0; k < 3; k ++)
{
for (int l = 0; l < 3; l ++)
{
edgeTemp5Data[i] += Template5[3 * k + l] * ((uchar*)(gray->data.ptr + (j + k - 1) * gray->step))[i + l - 1];
}
}
}
}
for (int j = 1; j < height - 1; j ++)
{
int* edgeTemp6Data = (int*)(edgeTemp6->data.ptr + j * edgeTemp6->step);
for (int i = 1; i < width - 1; i ++)
{
for (int k = 0; k < 3; k ++)
{
for (int l = 0; l < 3; l ++)
{
edgeTemp6Data[i] += Template6[3 * k + l] * ((uchar*)(gray->data.ptr + (j + k - 1) * gray->step))[i + l - 1];
}
}
}
}
for (int j = 1; j < height - 1; j ++)
{
int* edgeTemp7Data = (int*)(edgeTemp7->data.ptr + j * edgeTemp7->step);
for (int i = 1; i < width - 1; i ++)
{
for (int k = 0; k < 3; k ++)
{
for (int l = 0; l < 3; l ++)
{
edgeTemp7Data[i] += Template7[3 * k + l] * ((uchar*)(gray->data.ptr + (j + k - 1) * gray->step))[i + l - 1];
}
}
}
}
for (int j = 1; j < height - 1; j ++)
{
int* edgeTemp8Data = (int*)(edgeTemp8->data.ptr + j * edgeTemp8->step);
for (int i = 1; i < width - 1; i ++)
{
for (int k = 0; k < 3; k ++)
{
for (int l = 0; l < 3; l ++)
{
edgeTemp8Data[i] += Template8[3 * k + l] * ((uchar*)(gray->data.ptr + (j + k - 1) * gray->step))[i + l - 1];
}
}
}
}
int temp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
for (int j = 0; j < height; j ++)
{
uchar* edgeData = (uchar*)(edge->data.ptr + j * gray->step);
int* edgeTemp1Data = (int*)(edgeTemp1->data.ptr + j * edgeTemp1->step);
int* edgeTemp2Data = (int*)(edgeTemp2->data.ptr + j * edgeTemp2->step);
int* edgeTemp3Data = (int*)(edgeTemp3->data.ptr + j * edgeTemp3->step);
int* edgeTemp4Data = (int*)(edgeTemp4->data.ptr + j * edgeTemp4->step);
int* edgeTemp5Data = (int*)(edgeTemp5->data.ptr + j * edgeTemp5->step);
int* edgeTemp6Data = (int*)(edgeTemp6->data.ptr + j * edgeTemp6->step);
int* edgeTemp7Data = (int*)(edgeTemp7->data.ptr + j * edgeTemp7->step);
int* edgeTemp8Data = (int*)(edgeTemp8->data.ptr + j * edgeTemp8->step);
for (int i = 0; i < width; i ++)
{
temp[0] = edgeTemp1Data[i];
temp[1] = edgeTemp2Data[i];
temp[2] = edgeTemp3Data[i];
temp[3] = edgeTemp4Data[i];
temp[4] = edgeTemp5Data[i];
temp[5] = edgeTemp6Data[i];
temp[6] = edgeTemp7Data[i];
temp[7] = edgeTemp8Data[i];
int value = 0;
for (int k = 0; k< 8; k++)
{
value = temp[k] > value ? temp[k] : value;
}
if(value > 255)
value = 255;
if(value < 0)
value = 0;
edgeData[i] = value;
}
}
cvReleaseMat(&edgeTemp1);
cvReleaseMat(&edgeTemp2);
cvReleaseMat(&edgeTemp3);
cvReleaseMat(&edgeTemp4);
cvReleaseMat(&edgeTemp5);
cvReleaseMat(&edgeTemp6);
cvReleaseMat(&edgeTemp7);
cvReleaseMat(&edgeTemp8);
}
原图、灰度图和边缘图如下所示