opencv实现轮廓高斯滤波平滑

 更新时间:2020年07月21日 14:35:25   作者:BHY_  
这篇文章主要为大家详细介绍了opencv实现轮廓高斯滤波平滑,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了opencv实现轮廓高斯滤波平滑的具体代码,供大家参考,具体内容如下

一个小测试的题目:

在图像上点选,找到与点选处相邻的颜色相近的点集合,对该点集合提取轮廓,对该点集合轮廓平滑处理,显示处理结果。

#include <opencv2/opencv.hpp>
#include <iostream>
 
using namespace std;
using namespace cv;
 
 
//************************************
// Method: findRegion 漫水填充
// FullName: findRegion
// Access: public 
// Returns: vector<Point>
// Qualifier:
// Parameter: Mat img
// Parameter: Point pos
// Parameter: int LowDifference
// Parameter: int UpDifference
//************************************
vector<Point> findRegion(Mat img, Point pos, int LowDifference, int UpDifference)
{
 Mat image = img.clone();
 Mat imgBack = img.clone();
 Rect ccomp;
 Scalar pixel = image.at<Vec3b>(pos);
 Scalar pixel2 = Scalar(255 - pixel[0], 255 - pixel[1], 255 - pixel[2], pixel[3]);
 floodFill(image, pos, pixel2, &ccomp, Scalar(LowDifference, LowDifference, LowDifference),
 Scalar(UpDifference, UpDifference, UpDifference));
 
 Mat diff;
 absdiff(image, imgBack, diff);
 
 //统计所有非零像素
 vector<Point> pt;
 for (int i = 0; i < diff.rows; i++)
 {
 for (int j = 0; j < diff.cols; j++)
 {
 Point newPos(j, i);
 Scalar pixel3 = diff.at<Vec3b>(newPos);
 if (pixel3[0] != 0 || pixel3[1] != 0 || pixel3[2] != 0)
 {
 pt.push_back(newPos);
 }
 }
 }
 
 return pt;
}
 
//************************************
// Method: findPerimeter 从点集合中寻找轮廓点
// FullName: findPerimeter
// Access: public 
// Returns: vector<Point>
// Qualifier:
// Parameter: vector<Point> pt
// Parameter: Size size
//************************************
vector<Point> findPerimeter(vector<Point> pt, Size size)
{
 Mat imgGray(size, CV_8UC1, Scalar(0));
 for (int i = 0; i < pt.size(); i++)
 {
 imgGray.at<uchar>(pt[i]) = 255;
 }
 
 std::vector<std::vector<cv::Point>> contours;
 //获取轮廓不包括轮廓内的轮廓 
 cv::findContours(imgGray.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
 
 return contours[0];
}
 
//************************************
// Method: displayImage 显示图像
// FullName: displayImage
// Access: public 
// Returns: void
// Qualifier:
// Parameter: Mat img
// Parameter: vector<Point> contours 轮廓点
// Parameter: Point pos
//************************************
void displayImage(Mat img, vector<Point> contours, Point pos)
{
 Mat imgShow = img.clone();
 for (int i = 0; i < contours.size(); i++)
 {
 imgShow.at<Vec3b>(contours[i])[0] = 0;
 imgShow.at<Vec3b>(contours[i])[1] = 0;
 imgShow.at<Vec3b>(contours[i])[2] = 0;
 }
 
 circle(imgShow, pos, 3, Scalar(0, 0, 0), 1, 8, 0);//画用户选择的点
 
 imshow("img", imgShow);
 waitKey(0);
}
 
 
//************************************
// Method: findSmoothPeimeter 高斯滤波轮廓点平滑
// FullName: findSmoothPeimeter
// Access: public 
// Returns: void
// Qualifier:
// Parameter: Mat img 原图
// Parameter: vector<Point> pt 轮廓点集合
//************************************
void findSmoothPeimeter(Mat img, vector<Point> pt)
{
 vector<Point> contours = findPerimeter(pt, img.size());
 
 Mat im;
 cvtColor(img, im, CV_BGR2GRAY);
 
 Mat cont = ~im;
 Mat original = Mat::zeros(im.rows, im.cols, CV_8UC3);
 Mat smoothed = img.clone();
 
 // contour smoothing parameters for gaussian filter
 int filterRadius = 10;
 int filterSize = 2 * filterRadius + 1;
 double sigma = 10;
 
 size_t len = contours.size() + 2 * filterRadius;
 size_t idx = (contours.size() - filterRadius);
 vector<float> x, y;
 for (size_t i = 0; i < len; i++)
 {
 x.push_back(contours[(idx + i) % contours.size()].x);
 y.push_back(contours[(idx + i) % contours.size()].y);
 }
 // filter 1-D signals
 vector<float> xFilt, yFilt;
 GaussianBlur(x, xFilt, Size(filterSize, filterSize), sigma, sigma);
 GaussianBlur(y, yFilt, Size(filterSize, filterSize), sigma, sigma);
 // build smoothed contour
 vector<Point> smoothContours;
 for (size_t i = filterRadius; i < contours.size() + filterRadius; i++)
 {
 smoothContours.push_back(Point(xFilt[i], yFilt[i]));
 }
 
 Scalar color;
 
 for (int i = 0; i < smoothContours.size(); i++)
 {
 smoothed.at<Vec3b>(smoothContours[i])[0] = 0;
 smoothed.at<Vec3b>(smoothContours[i])[1] = 0;
 smoothed.at<Vec3b>(smoothContours[i])[2] = 0;
 }
 
 imshow("smoothed", smoothed);
 waitKey(10);
}
 
void main()
{
 Mat img = imread("4.jpg", 1);
 
 vector<Point> pt, contours;
 Point pos(1438, 590);//先列后行
 int para1 = 2;
 int para2 = 2;
 pt = findRegion(img, pos, para1, para2);
 findSmoothPeimeter(img, pt);
 
 contours = findPerimeter(pt, img.size());//轮廓点集合
 displayImage(img, contours, pos);//显示图像
}

漫水填充找到的轮廓

轮廓滤波平滑

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C++条件语句和条件运算符的使用方法讲解

    C++条件语句和条件运算符的使用方法讲解

    这篇文章主要介绍了C++条件语句和条件运算符的使用方法讲解,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C++使用map实现多进程拷贝文件的程序思路

    C++使用map实现多进程拷贝文件的程序思路

    这篇文章主要介绍了C++使用mmap实现多进程拷贝文件,通过本文给大家分享程序思路及完整代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • 使用devenv在命令行中编译项目的方法

    使用devenv在命令行中编译项目的方法

    下面小编就为大家分享一篇使用devenv在命令行中编译项目的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • C语言实现输出各种三角形

    C语言实现输出各种三角形

    这篇文章主要介绍了C语言实现输出各种三角形方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • C语言内存的动态分配比较malloc和realloc的区别

    C语言内存的动态分配比较malloc和realloc的区别

    这篇文章主要介绍了C语言内存的动态分配比较malloc和realloc的区别,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是本文的详细内容,需要的朋友可以参考下
    2021-07-07
  • C++中的类模板详解及示例

    C++中的类模板详解及示例

    我们在定义函数时,可以通过定义函数模板,来简化一些功能相同而数据类型不同的函数的定义和调用过程
    2013-10-10
  • 数据结构与算法 排序(冒泡,选择,插入)

    数据结构与算法 排序(冒泡,选择,插入)

    这篇文章主要介绍了数据结构与算法 排序(冒泡,选择,插入)的相关资料,这里对冒泡,选择和插入都做有实例,需要的朋友可以参考下
    2017-07-07
  • C++ OpenCV实现白平衡之完美反射算法

    C++ OpenCV实现白平衡之完美反射算法

    完美反射算法是白平衡各种算法中较常见的一种,比灰度世界算法更优。本文将利用C++和OpenCV实现白平衡中的完美反射算法,需要的可以参考一下
    2022-05-05
  • C++11中的原子量和内存序详解

    C++11中的原子量和内存序详解

    这篇文章主要给大家介绍了关于C++11中原子量和内存序的相关资料,文中通过示例代码介绍地方非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-06-06
  • C++ 网络编程 总结

    C++ 网络编程 总结

    这篇文章主要介绍了C++ 网络编程的一些详细相关内容,有需要的小伙伴可以参考下。
    2015-06-06

最新评论