#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; }
原图为
浮雕效果图如下