opencv3/C++輪廓的提取與篩選方式
輪廓提取
findContours發(fā)現(xiàn)輪廓
findContours( InputOutputArray binImg, //輸入8bit圖像,0值像素值不變,非0的像素看成1;(變?yōu)槎祱D像) OutputArrayOfArrays contours,//輸出找到的輪廓對(duì)象 OutputArray, hierachy// 圖像的拓?fù)浣Y(jié)構(gòu) int mode, //輪廓返回的模式(RETR_TREE等) int method,//發(fā)現(xiàn)方法(CHAIN_APPROX_SIMPLE等) Point offset=Point()//輪廓像素的位移(默認(rèn)沒有位移(0, 0)) )
【報(bào)錯(cuò)問題】
findContours()有時(shí)會(huì)報(bào)告“已觸發(fā)了一個(gè)斷點(diǎn)”等錯(cuò)誤,嘗試過y有效的解決方法有:
1.為vector提前申請(qǐng)一定的空間,如
std::vector<std::vector<Point>> contours(500)
2.Debug版切換為Release版;
drawContours繪制輪廓
drawContours( InputOutputArray binImg, // 輸出圖像 OutputArrayOfArrays contours,//找到的全部輪廓對(duì)象 Int contourIdx//輪廓索引號(hào) const Scalar & color,//繪制顏色 int thickness,//繪制線寬 int lineType ,//線的類型(默認(rèn)8) InputArray hierarchy,//拓?fù)浣Y(jié)構(gòu)圖 int maxlevel,//最大層數(shù)(0只繪制當(dāng)前的,1表示繪制繪制當(dāng)前及其內(nèi)嵌的輪廓) Point offset=Point()//輪廓位移 )
示例:
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat src,dst;
src = imread("E:/image/image/shape.jpg");
if(src.empty())
{
printf("can not load image \n");
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
dst = Mat::zeros(src.size(), CV_8UC3);
blur(src,src,Size(3,3));
cvtColor(src,src,COLOR_BGR2GRAY);
Canny(src, src, 20, 80, 3, false);
std::vector<std::vector<Point>> contours;
std::vector<Vec4i> hierarchy;
findContours(src, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
RNG rng(0);
for(int i = 0; i < contours.size(); i++)
{
Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255));
drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point(0,0));
}
namedWindow("output", CV_WINDOW_AUTOSIZE);
imshow("output",dst);
waitKey();
return 0;
}
使用opencv3時(shí)(測(cè)試用opencv3.1.0)發(fā)現(xiàn),cv命名空間下沒有了vector,而在opencv2中(測(cè)試用opencv2.4.10)還存在。后查看各自的頭文件發(fā)現(xiàn):
opencv.hpp頭文件中包含著core.hpp(#include “opencv2/core.hpp”);
而在opencv2的core.hpp中包含有
........ #include <map> #include <new> #include <string> #include <vector> .......
等頭文件,但在opencv3的core.hpp中刪去這些包含項(xiàng)。
因此在使用opencv3時(shí)cv命名空間下沒有了vector。
使用opencv2.4.10時(shí)可以寫:
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat src,dst;
src = imread("E:/image/image/shape.jpg");
if(src.empty())
{
printf("can not load image \n");
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
dst = Mat::zeros(src.size(), CV_8UC3);
blur(src,src,Size(5,5));
Canny(src, src, 20, 80, 3, false);
vector<vector<Point>>contours;
vector<Vec4i> hierarchy;
findContours(src, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
RNG rng(0);
for(int i = 0; i < contours.size(); i++)
{
Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255));
drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point(0,0));
}
namedWindow("output", CV_WINDOW_AUTOSIZE);
imshow("output",dst);
waitKey();
return 0;
}
繪制輪廓外矩形框
常用繪制輪廓外形狀的函數(shù):
cv::boundingRect(InputArray points)繪制一個(gè)矩形(輪廓周圍最小矩形左上角點(diǎn)和右下角點(diǎn))
cv::minAreaRect(InputArray points)繪制輪廓周圍最小旋轉(zhuǎn)矩形
cv::minEnclosingCircle(InputArray points, Point2f& center, float& radius)//繪制輪廓周圍最小圓形
cv::fitEllipse(InputArray points)繪制輪廓周圍最小橢圓
繪制輪廓外矩形框:
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat src,dst;
src = imread("E:/image/shape.jpg");
if(src.empty())
{
printf("can not load image \n");
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
dst = Mat::zeros(src.size(), CV_8UC3);
std::vector<std::vector<Point>>contours;
std::vector<Vec4i> hierarchy;
blur(src,src,Size(3,3));
cvtColor(src,src,COLOR_BGR2GRAY);
Canny(src, src, 20, 80, 3, false);
findContours(src, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
RNG rng(0);
std::vector<std::vector<Point>> contoursPloy(contours.size());
std::vector<RotatedRect> minRects(contours.size());
for(int i = 0; i < contours.size(); i++)
{
minRects[i] = minAreaRect(Mat(contours[i]));
Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255));
drawContours(dst, contoursPloy, i, color, 1,8,std::vector<Vec4i>(), 0, Point(0, 0));
Point2f rectPoints[4];
minRects[i].points(rectPoints);
for (int j = 0; j < 4; j++)
{
line(dst, rectPoints[j], rectPoints[(j+1)%4], color, 1, 8, 0);
}
}
namedWindow("output", CV_WINDOW_AUTOSIZE);
imshow("output",dst);
waitKey();
return 0;
}
輪廓篩選
moments( InputArray array,//輸入數(shù)據(jù) bool binaryImage=false //是否為二值圖像 ) contourArea( InputArray contour,//輸入輪廓數(shù)據(jù) bool oriented//返回絕對(duì)值(默認(rèn)false) ) arcLength( InputArray curve,//輸入輪廓 bool closed// 輪廓否是封閉曲線 )
輪廓篩選示例:
使用輪廓的面積和長(zhǎng)度特征對(duì)輪廓進(jìn)行篩選后用外接矩形將篩選后的輪廓框選出來。
#include<opencv2/opencv.hpp>
using namespace cv;
void trackBar(int,void*);
Mat src,dst;
std::vector<std::vector<Point>>contours;
int area = 0, length = 0;
int main()
{
src = imread("E:/image/shape.jpg");
if(src.empty())
{
printf("can not load image \n");
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
dst = Mat::zeros(src.size(), CV_8UC3);
std::vector<Vec4i> hierarchy;
blur(src,dst,Size(3,3));
cvtColor(dst,dst,COLOR_BGR2GRAY);
Canny(dst, dst, 20, 80, 3, false);
findContours(dst, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
namedWindow("output", CV_WINDOW_AUTOSIZE);
createTrackbar("area:", "output", &area,150,trackBar);
createTrackbar("length:", "output", &length,150,trackBar);
waitKey();
return 0;
}
void trackBar(int,void*)
{
Mat src1 = src.clone();
RNG rng(0);
std::vector<std::vector<Point>> contoursPloy(contours.size());
std::vector<RotatedRect> minRects(contours.size());
for(int i = 0; i < contours.size(); i++)
{
if(contourArea(contours[i]) > area && arcLength(contours[i], false) > length)
{
minRects[i] = minAreaRect(Mat(contours[i]));
Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255));
//drawContours(dst, contoursPloy, i, color, 1,8,vector<Vec4i>(), 0, Point(0, 0));
Point2f rectPoints[4];
minRects[i].points(rectPoints);
for (int j = 0; j < 4; j++)
{
line(src1, rectPoints[j], rectPoints[(j+1)%4], color, 2, 8, 0);
}
}
}
imshow("output",src1);
src1 = src;
}
以上這篇opencv3/C++輪廓的提取與篩選方式就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持我們。
上一篇:opencv3/C++ 實(shí)現(xiàn)SURF特征檢測(cè)
欄 目:C語(yǔ)言
下一篇:QString使用正則操作的接口實(shí)現(xiàn)
本文標(biāo)題:opencv3/C++輪廓的提取與篩選方式
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/101.html
您可能感興趣的文章
- 04-02c語(yǔ)言沒有round函數(shù) round c語(yǔ)言
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置


