#include <cv.h>
#include <highgui.h>
// 待擴充:浮雕的方向和高度
void kcvEmboss(const IplImage* src, IplImage* dst)
{
int w = src->width;
int h = src->height;
int cn = src->nChannels;
int sstep = src->widthStep;
int dstep = dst->widthStep;
const uchar* sptr = (uchar*)src->imageData;
uchar* dptr = (uchar*)dst->imageData;
sstep /= sizeof(sptr[0]);
dstep /= sizeof(dptr[0]);
const uchar* sptrCurr = sptr;
const uchar* sptrNext = sptr + sstep;
uchar* dptrCurr = dptr;
int tempVal = 0;
if (cn == 1)
{
for (int i = 0; i < h - 1; ++i)
{
for (int j = 0; j < w - 1; ++j)
{
tempVal = sptrNext[j + 1] - sptrCurr[j] + 128;
dptrCurr[j] = CV_CAST_8U(tempVal);
}
sptrCurr = sptrNext;
sptrNext += sstep;
dptrCurr += dstep;
}
}
else
{
for (int i = 0; i < h - 1; ++i)
{
for (int j = 0; j < w - 1; ++j)
{
tempVal = sptrNext[(j + 1) * 3 + 0] - sptrCurr[j * 3 + 0] + 128;
dptrCurr[j * 3 + 0] = CV_CAST_8U(tempVal);
tempVal = sptrNext[(j + 1) * 3 + 1] - sptrCurr[j * 3 + 1] + 128;
dptrCurr[j * 3 + 1] = CV_CAST_8U(tempVal);
tempVal = sptrNext[(j + 1) * 3 + 2] - sptrCurr[j * 3 + 2] + 128;
dptrCurr[j * 3 + 2] = CV_CAST_8U(tempVal);
}
sptrCurr = sptrNext;
sptrNext += sstep;
dptrCurr += dstep;
}
}
}
void kcvEmboss2(const IplImage* src, IplImage* dst)
{
int w = src->width;
int h = src->height;
int cn = src->nChannels;
int sstep = src->widthStep;
int dstep = dst->widthStep;
const uchar* sptr = (uchar*)src->imageData;
uchar* dptr = (uchar*)dst->imageData;
sstep /= sizeof(sptr[0]);
dstep /= sizeof(dptr[0]);
const uchar* sptrCurr = sptr;
const uchar* sptrNext = sptr + sstep;
uchar* dptrCurr = dptr;
int tempVal = 0;
for (int i = 0; i < h - 1; ++i)
{
for (int j = 0; j < (w - 1) * cn; ++j)
{
tempVal = sptrNext[j + cn] - sptrCurr[j] + 128;
dptrCurr[j] = CV_CAST_8U(tempVal);
}
sptrCurr = sptrNext;
sptrNext += sstep;
dptrCurr += dstep;
}
}
int main()
{
IplImage *src = cvLoadImage("lena.jpg", 1);
IplImage *dst = cvCloneImage(src);
cvShowImage("src", src);
int64 t1, t2;
int iterNum = 10;
float kernel[4] =
{
-1.0, 0.0,
0.0, 1.0
};
CvMat km = cvMat(2, 2, CV_32F, kernel);
t1 = cvGetTickCount();
for (int i = 0; i < iterNum; ++i)
{
cvFilter2D(src, dst, &km, cvPoint(0, 0));
}
cvScale(dst, dst, 1, 128);
t2 = cvGetTickCount();
printf("cvFilter2D %f ms\n", (t2 - t1) / (1000 * cvGetTickFrequency()));
cvShowImage("cvFilter2D", dst);
t1 = cvGetTickCount();
for (int i = 0; i < iterNum; ++i)
{
kcvEmboss(src, dst);
}
t2 = cvGetTickCount();
printf("kcvEmboss %f ms\n", (t2 - t1) / (1000 * cvGetTickFrequency()));
cvShowImage("kcvEmboss", dst);
t1 = cvGetTickCount();
for (int i = 0; i < iterNum; ++i)
{
kcvEmboss2(src, dst);
}
t2 = cvGetTickCount();
printf("kcvEmboss2 %f ms\n", (t2 - t1) / (1000 * cvGetTickFrequency()));
cvShowImage("kcvEmboss2", dst);
cvWaitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&dst);
return 0;
}
原圖為
浮雕效果圖如下