图像处理软件中,如PhotoShop,免费开源的位图形编辑GIMP软件中,对图像进行特效的浮雕或雕刻功能。本节介绍使用OpenCV实现图像特效之浮雕和雕刻相关知识,并贴出相关参考代码以及输出测试图像效果图。
浮雕/雕刻算法实质是很简单地,即:对图像的每一个点进行卷积处理。假设原图像为X,处理后的图像为Y;浮雕算法核kernel矩阵定义为:[1 , 0, 0 ; 0, 0, 0; 0, 0, -1]. 那么,对于坐标为(i,j)点,浮雕效果图的算法为Y(i,j) = X(i+1,j+1)-X(i-1,j-1) + 128。当然,X,Y的取值均在0~255之间。雕刻算法核kernel矩阵定义为:[1, 0; 0, -1]。那么,对于坐标为(i,j)点,其浮雕效果图的算法为Y(i,j) = X(i,j) - X(i-1,j-1) + 128。当然,X,Y的取值均在0~255之间。
在OpenCV2中,filter2D函数定义:
//! applies non-separable 2D linear filter to the image CV_EXPORTS_W void filter2D( InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT );
/////////////////////////////////////////////////////////// //Parameters: // pImg: input image // flags: IMAGECAMEO_0 : sign sculputre in image processing // IMAGECAMEO_1 : sign engrave in image processing /////////////////////////////////////////////////////////// IplImage *ImageEffect::ImageCameo(IplImage *pImg, int flags) { if(!pImg){ printf("Errror: Load File in ImageCameo(.).\n"); exit(EXIT_FAILURE); } nWidth = pImg->width; nHeight = pImg->height; pImgdata =(uchar*) pImg->imageData; pImgChannels = pImg->nChannels; step = pImg->widthStep; int temp0,temp1,temp2; for(int i =0; i<nWidth-1; i++){ for( int j =0; j<nHeight-1;j++){ if(pImgChannels ==1){ // gray image if(flags ==IMAGECAMEO_0){ //sculputre processing temp0 = pImgdata[(j+1)*step+(i+1)*pImgChannels]- pImgdata[j*step+i*pImgChannels]+128; } if(flags ==IMAGECAMEO_1){ //engrave processing temp0 = pImgdata[j*step+i*pImgChannels]- pImgdata[(j+1)*step+(i+1)*pImgChannels] +128; } if(temp0>255) pImgdata[j*step+i*pImgChannels] = 255; if(temp0<0) pImgdata[j*step+i*pImgChannels] = 0; else pImgdata[j*step+i*pImgChannels] = temp0; } if(pImgChannels ==3){ // color image if(flags == IMAGECAMEO_0){ //sculputre processing temp0 = pImgdata[(j+1)*step+(i+1)*pImgChannels]- pImgdata[j*step+i*pImgChannels] +128; temp1 = pImgdata[(j+1)*step+(i+1)*pImgChannels+1]- pImgdata[j*step+i*pImgChannels+1] +128; temp2 = pImgdata[(j+1)*step+(i+1)*pImgChannels+2]- pImgdata[j*step+i*pImgChannels+2] +128; } if(flags == IMAGECAMEO_1){ //engrave processing temp0 = pImgdata[j*step+i*pImgChannels]- pImgdata[(j+1)*step+(i+1)*pImgChannels]+128; temp1 = pImgdata[j*step+i*pImgChannels+1]- pImgdata[(j+1)*step+(i+1)*pImgChannels+1]+128; temp2 = pImgdata[j*step+i*pImgChannels+2]- pImgdata[(j+1)*step+(i+1)*pImgChannels+2]+128; } if(temp0>255) pImgdata[j*step+i*pImgChannels] = 255; if(temp0<0) pImgdata[j*step+i*pImgChannels] = 0; else pImgdata[j*step+i*pImgChannels] = temp0; if(temp1>255) pImgdata[j*step+i*pImgChannels+1] = 255; if(temp1<0) pImgdata[j*step+i*pImgChannels+1] = 0; else pImgdata[j*step+i*pImgChannels+1] = temp1; if(temp2>255) pImgdata[j*step+i*pImgChannels+2] = 255; if(temp2<0) pImgdata[j*step+i*pImgChannels+2] = 0; else pImgdata[j*step+i*pImgChannels+2] = temp2; } } } return pImg; }
(a)源始图像 (b)浮雕图像效果 (c)雕刻图像效果
(d)源始图像 (e)浮雕图像效果 (f)雕刻图像效果
(g)源始图像 (h)浮雕图像效果 (i)雕刻图像效果
cv::Mat ImageEffort::ImageCameo(cv::Mat &pMat,int flags) { if(!pMat.data){ std::cout<<"Error:Load File."<<std::endl; exit(EXIT_FAILURE); } cv::Mat m1 =(cv::Mat_<char>(2,2)<< 1,0,0,-1); cv::Mat m2 =(cv::Mat_<char>(2,2)<<-1,0,0, 1); cv::Mat dst; if(flags == CV_IMAGECAMEO_0){ cv::filter2D(pMat,dst,pMat.depth(),m1,cv::Point(0,0)); } if(flags == CV_IMAGECAMEO_1){ cv::filter2D(pMat,dst,pMat.depth(),m2,cv::Point(0,0)); } dst +=128; return dst; }
(a)源始图像 (b)浮雕图像效果 (c)雕刻图像效果
(d)源始图像 (e)浮雕图像效果 (f)雕刻图像效果
(g)源始图像 (h)浮雕图像效果 (i)雕刻图像效果
测试结果分析:通过输出图像效果图,我们可知是对图像中B通道进行处理了,并不理想。
cv::Mat ImageEffort::ImageCameo_O(cv::Mat &pMat, int flags) { if(!pMat.data){ std::cout<<"Error: Load FILE"<<std::endl; exit(EXIT_SUCCESS); } cv::Mat img(pMat.size(),CV_8UC3); int tmp; for(int j = 1; j<pMat.rows-1;j++){ uchar* p0 = pMat.ptr<uchar>(j); uchar* p1 = pMat.ptr<uchar>(j+1); uchar *q = img.ptr<uchar>(j); for(int i = 1; i<pMat.cols-1; i++){ for(int k =0; k <3; k++){ if(flags == CV_IMAGECAMEO_0){ tmp = p1[3*(i+1)+k]-p0[3*(i-1)+k]+128 ; } if(flags ==CV_IMAGECAMEO_1){ tmp = p1[3*(i-1)+k]-p0[3*(i+1)+k]+128; } if(tmp <0) q[3*i+k] =0; if(tmp >255) q[3*i+k] =255; else q[3*i+k] = tmp; } } } return img; }
(a)源始图像 (b)浮雕图像效果 (c)雕刻图像效果
(d)源始图像 (e)浮雕图像效果 (f)雕刻图像效果
(g)源始图像 (h)浮雕图像效果 (i)雕刻图像效果
关于Image Engineering & Computer Vision的更多讨论与交流,敬请关注本博和新浪微博songzi_tea.