当前位置: 首页 > news >正文

网站推广营销方案/太原seo全网营销

网站推广营销方案,太原seo全网营销,珍岛公司推广靠谱吗,北京疫情宣布解除时间问题描述: 关键字:VS2015、Opencv、形状、周长、面积、轮廓提取 在很多时候我们需要对一些形状进行识别,其中包括对形状的区分、对图像的提取、对面积和周长的计算等等,这时我们可以利用opencv进行运用从而实现目的。 本篇文章…

问题描述:

关键字VS2015、Opencv、形状、周长、面积、轮廓提取

在很多时候我们需要对一些形状进行识别,其中包括对形状的区分、对图像的提取、对面积和周长的计算等等,这时我们可以利用opencv进行运用从而实现目的。

本篇文章源于有一次同学提出了一个问题:存在一张图片如下,把图中的红色内容提出来,并且识别形状(正三角形,圆形,正方形),计算面积,周长,边长,中心点,接下来我们就用VS2015+Opencv4来实现它!
在这里插入图片描述

主要流程:

基于硬核求解原则,咱们用最现成的方法、最简单的思路对问题进行求解。

老规矩先来波预操作:先给咱们的图来滤个波、二值化然后再进行形态学操作,然后我们就能得到一个清晰的二值图了

得到二值图像后咱们就要把他的轮廓提取出来,这里主要是利用finfContours()函数找出图形轮廓,找出各个轮廓后用drawContours()函数绘出轮廓,注意在这里要加入一个轮廓大小判断是否等于窗口面积,否则会将窗口识别成矩形绘出。

接下来先检测出圆形,这里可以利用一个常见的霍夫圆检测函数来检测圆形,利用获得的圆心和半径可以确定圆的位置和大小,从而绘出。

然后对矩形和三角形进行多边拟合操作,利用approxPolyDP()函数
对图像轮廓点进行多边形拟合,对于拟合的结果我们可以进行一个简单的筛选,以便于筛掉过小的拟合矩形。三角形以及其他多边形的拟合操作都与矩形类似。

根据拟合结果我们就能得到各个图形的顶点和边长,从而我们就能利用line()函数将不同的几何形状用不同的颜色描绘出来。
同时我们也可以通过contourArea()函数和arcLength()函数计算出各个图形的面积与周长。

代码实现:

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
#define pi 3.14
using namespace cv;
using namespace std;Mat src;
int main(int argc, char** argv)
{src = imread("D:\\我的文档\\Visual Studio 2015\\Projects\\images\\demo.jpg");if (src.empty()){printf("图片未找到!!!");return -1;}imshow("input image", src);//高斯模糊Mat GaussImg;//medianBlur(src, GaussImg,5);//中值滤波GaussianBlur(src, GaussImg, Size(7, 7), 0, 0);//高斯滤波imshow("Gauss Image", GaussImg);cvtColor(GaussImg, GaussImg, COLOR_BGR2GRAY);//二值化操作Mat binary;threshold(GaussImg, binary, 128, 255, THRESH_BINARY);imshow("binary Image", binary);//形态学操作Mat morphImg;Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));morphologyEx(binary, morphImg, MORPH_CLOSE, kernel, Point(-1, -1), 1);imshow("morph Image", morphImg);//阈值分割Mat contoursIm;threshold(morphImg, contoursIm, 0, 255, THRESH_BINARY + THRESH_OTSU);imshow("阈值分割", contoursIm);//轮廓发现Mat contoursImg = Mat::zeros(src.size(), CV_8UC3);vector<vector<Point>>contours;//存储二维浮点型向量,这里面将来会存储找到du的边界的(x,y)坐标vector<Vec4i>hierarchy;//定义的层级。这个在找边界findcontours的时候会自动生成,这里只是给它开辟一个空间findContours(contoursIm, contours, RETR_LIST, CHAIN_APPROX_NONE);//保存物体边界上所有连续的轮廓点到contours向量内int flags = 0;for (size_t i = 0; i < contours.size(); i++){Rect rect = boundingRect(contours[i]);if (rect.height == src.rows){flags = 1;contours.pop_back();}if (flags == 0){drawContours(contoursImg, contours, static_cast<int>(i),Scalar(0, 0, 255), 2, 8, hierarchy, 0, Point(0, 0));}flags = 0;}vector<Point>triangle;vector<Point>approx;vector<Point>squares;vector<Vec3f>circles;//圆HoughCircles(GaussImg, circles, HOUGH_GRADIENT, 1, src.rows / 20, 100, 60, 0, 0);//rows/20为检测圆之间距离,100为传递给canny边缘检测算子的高阈值,60(它越小则可以检测到更多跟本不存在的圆,两个0为半径默认值)Mat dstImg(morphImg.rows, morphImg.cols, CV_8UC3, Scalar(255, 255, 255));for (size_t i = 0; i < circles.size(); i++)//画圆{Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));int radius = cvRound(circles[i][2]);circle(dstImg, center, radius, Scalar(0, 255, 0), 5, 8, 0);circle(dstImg, center, 3, Scalar(0, 255, 0), -1);cout << "圆形" << i + 1 << "中心" << center << endl;cout << "圆" << i + 1 << "的面积为:" << pi*radius*radius << endl;cout << "圆" << i + 1 << "的周长为:" << pi * 2 * radius << endl;}//多边形拟合操作for (size_t i = 0; i < contours.size(); i++){approxPolyDP(contours[i], approx, arcLength(Mat(contours[i]), true)*0.02, true);                     //主要功能是把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合。if (approx.size() == 4 && fabs(contourArea(Mat(approx))) > 1000 && isContourConvex(Mat(approx))){double minDist = 1e10;for (int i = 0; i < 4; i++){Point side = approx[i] - approx[(i + 1) % 4];double squaredSideLength = side.dot(side);minDist = min(minDist, squaredSideLength);}if (minDist<50)break;for (int i = 0; i<4; i++)squares.push_back(Point(approx[i].x, approx[i].y));}approxPolyDP(contours[i], approx, arcLength(Mat(contours[i]), true)*0.1, true);if (approx.size() == 3 && fabs(contourArea(Mat(approx))) > 1000 && isContourConvex(Mat(approx))){double minDist = 1e10;for (int i = 0; i <3; i++){Point side = approx[i] - approx[(i + 1) % 3];double squaredSideLength = side.dot(side);minDist = min(minDist, squaredSideLength);}if (minDist<50)break;for (int i = 0; i<3; i++)triangle.push_back(Point(approx[i].x, approx[i].y));}drawContours(dstImg, contours, i, Scalar(0, 0, 255), 3);}for (size_t i = 0; i < squares.size(); i += 4)//描边操作{Point center;center.x = (squares[i].x + squares[i + 2].x) / 2;center.y = (squares[i].y + squares[i + 2].y) / 2;line(dstImg, squares[i], squares[i + 1], Scalar(255, 0, 255), 4);line(dstImg, squares[i + 1], squares[i + 2], Scalar(255, 0, 255), 4);line(dstImg, squares[i + 2], squares[i + 3], Scalar(255, 0, 255), 4);line(dstImg, squares[i + 3], squares[i], Scalar(255, 0, 255), 4);cout << "矩形" << (i + 1) % 4 << "中心" << center << endl;cout << "矩形" << i + 1 << "的面积为:" << contourArea(squares) << endl;cout << "矩形" << i + 1 << "的周长为:" << arcLength(squares, true) << endl;circle(dstImg, center, 3, Scalar(255, 0, 255), -1);}for (size_t i = 0; i < triangle.size(); i += 3){Point center;center.x = (triangle[i].x + triangle[i + 1].x + triangle[i + 2].x) / 3;center.y = (triangle[i].y + triangle[i + 1].y + triangle[i + 2].y) / 3;line(dstImg, triangle[i], triangle[i + 1], Scalar(255, 0, 0), 4);line(dstImg, triangle[i + 1], triangle[i + 2], Scalar(255, 0, 0), 4);line(dstImg, triangle[i], triangle[i + 2], Scalar(255, 0, 0), 4);cout << "三角形" << (i + 1) % 3 <<"中心" <<center << endl;cout << "三角形" << i + 1 << "的面积为:" << contourArea(triangle) << endl;cout << "三角形" << i + 1 << "的周长为:" << arcLength(triangle, 1) << endl;circle(dstImg, center, 3, Scalar(255, 0, 0), -1);}//显示提取图像Mat extract(src.size(), CV_8UC3, Scalar(255, 255, 255));for (size_t i = 0; i < squares.size(); i += 4)//描边操作{Point center;center.x = (squares[i].x + squares[i + 2].x) / 2;center.y = (squares[i].y + squares[i + 2].y) / 2;line(extract, squares[i], squares[i + 1], Scalar(255, 0, 255), 4);line(extract, squares[i + 1], squares[i + 2], Scalar(255, 0, 255), 4);line(extract, squares[i + 2], squares[i + 3], Scalar(255, 0, 255), 4);line(extract, squares[i + 3], squares[i], Scalar(255, 0, 255), 4);circle(extract, center, 3, Scalar(255, 0, 255), -1);}for (size_t i = 0; i < triangle.size(); i += 3){Point center;center.x = (triangle[i].x + triangle[i + 1].x + triangle[i + 2].x) / 3;center.y = (triangle[i].y + triangle[i + 1].y + triangle[i + 2].y) / 3;line(extract, triangle[i], triangle[i + 1], Scalar(255, 0, 0), 4);line(extract, triangle[i + 1], triangle[i + 2], Scalar(255, 0, 0), 4);line(extract, triangle[i], triangle[i + 2], Scalar(255, 0, 0), 4);circle(extract, center, 3, Scalar(255, 0, 0), -1);}for (size_t i = 0; i < circles.size(); i++)//画圆{Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));int radius = cvRound(circles[i][2]);circle(extract, center, radius, Scalar(0, 255, 0), 5, 8, 0);circle(extract, center, 3, Scalar(0, 255, 0), -1);}imshow("轮廓提取", extract);imshow("形状检测", dstImg);waitKey(0);return 0;}

运行结果:

滤波图像:
在这里插入图片描述
二值图像:
在这里插入图片描述
图形提取与区分:
在这里插入图片描述
图形中心坐标、图形面积与周长计算结果:
在这里插入图片描述

小小总结:

本次所运用的方法存在一定的局限性,识别图形的范围有限,比如难以识别扇形、凹形等等,不过对于比较常规的多边形识别确很有效,同时也可以拓展到调用Video进行实时的规则形状识别,还有地方值得提升拓展,欢迎大家交流。

http://www.lbrq.cn/news/1594549.html

相关文章:

  • 西宁市网站建设公司/店铺引流的30种方法
  • 可以做h5的网站/手机搜索引擎排行榜
  • 网站后台怎么添加代码/武汉网站搜索引擎优化
  • 中企做的网站太原/北京网站建设制作开发
  • 网站开发要求有哪些/搜索引擎营销seo
  • 合肥新站区有做网站的吗/汕头企业网络推广
  • 广州做网站优化公司报价/ip网站查询服务器
  • 用html做网站/广告营销推广方案
  • discuz主题/seo推广的网站和平台有哪些
  • 最近很火的营销事件/百度seo排名规则
  • 广安住房和城乡建设厅网站/东莞网站设计公司
  • 金光华网站建设/长沙本地推广联系电话
  • 衡阳网站建设报价方案/长春百度网站快速排名
  • 织梦网站怎么更换模板/广州网站优化排名
  • 专业建站公司报价/武汉seo软件
  • 电脑登录不了建设银行网站/seo网络推广课程
  • 做印刷网站公司哪家好/网站cms
  • 电脑版网页/郑州网站seo顾问
  • 业务网站建设/西安做网站
  • 做美团类似的网站/小红书软文案例
  • 开发大型网站的流程/杭州网站优化推荐
  • 苏州前几天网站建设/文章优化关键词排名
  • 汉口做网站jw100/百度客服24小时人工服务
  • 私服网站建设/品牌推广的渠道有哪些
  • wordpress获得授权/成都高薪seo
  • 网站做的最好的/百度seo在线优化
  • 深圳罗湖网站制作公司哪家好/凡科网建站系统源码
  • 个人网站毕业设计论文/长沙网站推广服务公司
  • 如何拥有一个自己的网站/如何做好品牌宣传
  • jsp动态网站开发案例教程下载/什么是优化师
  • 「iOS」————单例与代理
  • 【C语言】文件操作全解析
  • 笔试——Day29
  • Dubbo-Go调Bug记录-泛化调用调不通
  • 3.JVM,JRE和JDK的关系是什么
  • 【ECCV2024】AdaCLIP:基于混合可学习提示适配 CLIP 的零样本异常检测