OpenCV无缝融合应用(四)--纹理平滑(附C++源码)

导读

本期将介绍并演示OpenCV中使用textureFlattening实现图像中指定区域纹理平滑的效果。

介绍

OpenCV图像无缝融合-seamlessClone介绍与使用(Python/C++源码)

OpenCV无缝融合应用(二)--指定目标颜色改变(附C++源码)

OpenCV无缝融合应用(三)--局部区域亮度调整(附C++源码)

textureFlattening与上述三种方法同属于Seamless Cloning部分,算法均来自下面这篇论文:图片

https://www.cs.jhu.edu/~misha/Fall07/Papers/Perez03.pdf

百度网盘下载:

链接:https://pan.baidu.com/s/1Ma_9ZF4r0SgNmfygHe3kgQ

提取码:0857

算法解读可参考下面链接:

https://blog.csdn.net/zhaoyin214/article/details/88196575

图片

在与Poisson求解器集成之前,通过仅保留边缘位置处的梯度,可以冲洗所选区域的纹理,使其内容具有平坦的外观。这里使用Canny Edge Detector。该算法假定源图像的颜色接近目标图像的颜色。这种假设意味着,当颜色不匹配时,源图像的颜色将趋向于目标图像的颜色。边缘检测器选取的边缘越少(选择性越强),边缘映射就越稀疏,扁平化效果就越明显。函数说明:

图片

参数:

src输入8位3通道图像
mask输入8位1或3通道图像(掩码图像)
dst输出结果图(要求和src相同的大小和类型)
low_thresholdCanny边缘检测器低阈值(建议取值0~100)
high_thresholdCanny边缘检测器高阈值(建议取值>100)
kernel_sizeSobel核大小,默认值3

效果展示

实现指定区域纹理平滑(全局人像处理有点类似油画效果):

图片

图片

实现步骤与源码

程序实现步骤:

(1) 使用鼠标滑动绘制指定目标并生成mask;

(2) 使用;两个滑动条动态改变low_threshold和high_threshold参数的值;

(3) 滑动条回调函数中使用textureFlattening函数完成纹理平滑。

src图:

图片

鼠标拖动勾选人的轮廓部分(low_thres=72, high_thres=0)以及运行结果:

图片

鼠标拖动勾选人的轮廓部分(low_thres=72, high_thres=145)以及运行结果:

图片

其他效果大家可以自行尝试,完整C++源码如下:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int low_thres = 30, high_thres = 45;
Mat src, temp, mask, result;
Rect rect;

Point pt;
bool flag = false;

void OnChange(int, void*)
{
  //Mat mask = Mat::zeros(src.size(), src.type());
  //rectangle(mask, rect, Scalar::all(255), -1);
  //illuminationChange(src, mask, result, alpha / 100.0, beta / 100.0);
  textureFlattening(src, mask, result, low_thres, high_thres, 3);
  imshow("textureFlattening", result);
}

///鼠标消息回调函数
void OnMouse(int event, int x, int y, int flag, void* param)
{
  switch (event)
  {
  case EVENT_LBUTTONDOWN:  //鼠标左键按下
    //cout<<"left button down"<<endl;
    flag = true;
    pt.x = x;
    pt.y = y;
    break;
  case EVENT_MOUSEMOVE:   //鼠标移动
    //cout<<"mouse move"<<endl;
    if (flag)
    {
      circle(temp, Point(x, y), 5, Scalar(0, 0, 255), -1, 8);
      circle(mask, Point(x, y), 5, Scalar(255, 255, 255), -1, 8);
    }
    break;
  case EVENT_LBUTTONUP:   //鼠标左键弹起
    //cout<<"left button up"<<endl;
    flag = false;
    break;
  default:
    break;
  }
}


int main()
{
  src = imread("B.jpg");
  temp = src.clone();
  mask = Mat::zeros(src.size(), CV_8UC1);
  namedWindow("src", WINDOW_NORMAL);
  imshow("src", src);
  namedWindow("Mouse", WINDOW_NORMAL);
  setMouseCallback("Mouse", OnMouse, 0);   //设置鼠标回调函数
  while (1)
  {
    imshow("Mouse", temp);
    if (27 == waitKey(10))  //Esc跳出循环
      break;
  }
  vector<vector<Point>> contours;
  vector<Vec4i> hierarcy;

  findContours(mask, contours, hierarcy, RETR_EXTERNAL, CHAIN_APPROX_NONE);
  drawContours(mask, contours, -1, Scalar::all(255), -1, 8);

  namedWindow("textureFlattening", WINDOW_NORMAL);
  createTrackbar("low_thres", "textureFlattening", &low_thres, 500, OnChange);
  createTrackbar("high_thres", "textureFlattening", &high_thres, 500, OnChange);
  OnChange(0, 0);
  waitKey();
  return 0;
}

后记:貌似纹理平滑的效果没什么大用,但这部分功能同属无缝克隆部分,所以这里还是做简短介绍。到这里,OpenCV无缝克隆部分算是完结了,也算是有始有终吧!下篇文章开始将进入2020 Top 10 OpenCV Projects分篇讲解,敬请期待!如果您忘了有哪些内容,可点击上面↑蓝字链接观看。

更多视觉图像处理相关内容,请长按关注:OpenCV与AI深度学习。

图片

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Color Space

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值