天天看點

圖像特效之浮雕(OpenCV)

#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;
}
           

原圖為

圖像特效之浮雕(OpenCV)

浮雕效果圖如下

圖像特效之浮雕(OpenCV)