图像处理软件中,如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; i255) 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."<(2,2)<< 1,0,0,-1);
cv::Mat m2 =(cv::Mat_(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"<(j);
uchar* p1 = pMat.ptr(j+1);
uchar *q = img.ptr(j);
for(int i = 1; i255) 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.