最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++利用opencv實(shí)現(xiàn)單目測(cè)距的實(shí)現(xiàn)示例

 更新時(shí)間:2021年11月11日 09:48:23   作者:知道什么是碼怪嗎?  
本文主要介紹了C++利用opencv實(shí)現(xiàn)單目測(cè)距的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

閑來無事,用C++做了一個(gè)簡(jiǎn)易的單目測(cè)距。算法用的cv自帶的,改改參數(shù)就行。實(shí)現(xiàn)了讀取照片測(cè)距,讀取筆記本攝像頭測(cè)距,讀取視頻測(cè)距三個(gè)功能。

為什么不用雙目測(cè)距?因?yàn)闆]錢買攝像頭……

原理:相似三角形原理,已知焦距的情況下檢測(cè)被測(cè)物在圖片中所占的像素寬度來判斷被測(cè)物與攝像頭的距離,同時(shí)也可以得出被測(cè)物的大概長寬。注意:攝像頭要和被測(cè)物體平行,如果不平行在側(cè)面看來攝像頭和物體之間的連線就與水平方向有一個(gè)夾角a,被測(cè)物體在圖片中的大小會(huì)受到影響,從而影響測(cè)量效果。

誤差分析:導(dǎo)致測(cè)量效果不好的原因有很多,比如說攝像頭與被測(cè)物沒有在同一高度,攝像頭標(biāo)定的焦距不準(zhǔn)確,不同視頻拍攝的攝像頭焦距不同,測(cè)量出來也不一樣,所以測(cè)量前需要對(duì)攝像頭進(jìn)行標(biāo)定處理得到焦距,這里使用的是傳統(tǒng)的標(biāo)定方法。

步驟:

①標(biāo)定得出焦距

②對(duì)圖片進(jìn)行高斯濾波處理(平滑操作,過濾操作,去噪操作)

③邊緣檢測(cè)

④畫出檢測(cè)出的輪廓并返回最小的外接矩形(可以設(shè)置畫出全部輪廓或者是最大的輪廓)

⑤計(jì)算距離

檢測(cè)攝像頭只需要把攝像頭獲取到的畫面逐幀分析,就相當(dāng)于對(duì)照片分析,視頻也是一個(gè)道理。這里我設(shè)置了一個(gè)保存最小距離和最大距離的變量,當(dāng)然這只能作為一個(gè)參考值并不是準(zhǔn)確的,因?yàn)閿z像頭和視頻測(cè)距都沒有和被測(cè)物平行。

效果演示:

效果不穩(wěn)定,對(duì)于單張圖片效果有時(shí)候誤差只有幾厘米,有時(shí)候誤差就幾十厘米甚至超過一百厘米。這個(gè)測(cè)量的距離是圖片中檢測(cè)到的最小矩形到攝像頭的距離,所以對(duì)于背景比較干凈的矩形圖片很好識(shí)別,識(shí)別的很規(guī)整,但是對(duì)于一些背景雜亂的圖片,識(shí)別效果就差強(qiáng)人意。這里以兩種不同的圖片做對(duì)比。

其對(duì)應(yīng)的圖片處理效果如下(實(shí)際誤差只有1厘米):

對(duì)于陽臺(tái)的一棵樹:

我也不知道我和這棵樹距離有好遠(yuǎn),測(cè)出來163cm,但是肯定超過了這個(gè)距離。

代碼(拿了代碼記得點(diǎn)贊評(píng)論一波哦):

沒有分文件編寫,配置好opencv就可以直接用,效果不保證,也就圖一樂。

#include <opencv2/opencv.hpp>
#include <iostream>
 
using namespace cv;
using namespace std;
//2903.85   2438.65   2904.1
#define KNOWN_DISTANCE  70.866		//已知距離
#define KNOWN_WIDTH   0.787		//已知寬度0.787    11.69
#define KNOWN_HEIGHT  0.787	//已知高度0.787    8.27
//需要提前獲取,通過標(biāo)定步驟獲得的
#define KNOWN_FOCAL_LENGTH  3000  //已知焦距
 
double MaxDistance= DBL_MIN;//最大距離
double MinDistance= DBL_MAX;//最小距離
void GetPicture(Mat& SrcImage, int choice);
void GetCamera(int choice);
void GetVideo(int choice);
double GetTheDistanceToCamera(double KnownWidth, double FocalLength, double PerWidth);
double CalculateFocalDistance(Mat& Image);
RotatedRect FindMarker(Mat& SrcImage);
 
A4紙尺寸:210mm×297mm(16開紙)
int main(int argv, char* argc[])
{	
	int choice = 0;
	cout << "請(qǐng)輸入你想選擇的模式" << endl;
	cout << "識(shí)別圖片請(qǐng)輸入:1" << endl;
	cout << "實(shí)時(shí)攝像頭識(shí)別請(qǐng)輸入:2" << endl;
	cout << "讀取視頻請(qǐng)輸入:3" << endl;
	
	cin >> choice;
	if (choice == 1 ){
		Mat SrcImage = imread("輸入圖片絕對(duì)路徑在這里.jpg", IMREAD_COLOR);//獲取圖片
		GetPicture(SrcImage,choice);
		cout << "圖像中檢測(cè)過的輪廓中,最大距離為:" << MaxDistance << "cm" << endl;
		cout << "圖像中檢測(cè)過的輪廓中,最小距離為:" << MinDistance << "cm" << endl;
	}
	else if (choice == 2) {
		GetCamera(choice);
	}
	else if (choice == 3) {
		GetVideo(choice);
	}
	
}
 
void GetPicture(Mat& SrcImage,int choice) {
	
	//以下程序用于標(biāo)定相機(jī)獲得“焦距”
	namedWindow("輸入窗口", 0);
	resizeWindow("輸入窗口", 600, 600);//限定窗口大小
	imshow("輸入窗口", SrcImage);//輸出窗口
	double FocalLength = 0.0;
	FocalLength = CalculateFocalDistance(SrcImage);  //獲得焦距
 
	//以下程序用于實(shí)際計(jì)算距離
	RotatedRect Marker;
	Marker = FindMarker(SrcImage);
	double DistanceInches = 0.0;
	
	DistanceInches = GetTheDistanceToCamera(KNOWN_WIDTH, KNOWN_FOCAL_LENGTH, Marker.size.width); //計(jì)算相機(jī)與目標(biāo)之間的距離
	DistanceInches = DistanceInches * 2.54;  //轉(zhuǎn)換成cm  1英寸=2.54厘米
	//獲取檢測(cè)到的最大最小距離的范圍
 
	if (DistanceInches > MaxDistance)
		MaxDistance = DistanceInches;
	if (DistanceInches < MinDistance)
		MinDistance = DistanceInches;
	cout << "DistanceInches(cm):" << DistanceInches << endl;  //顯示的單位為厘米
	putText(SrcImage, format("distance:%f", DistanceInches), Point(100, 100), FONT_HERSHEY_SIMPLEX, 2, Scalar(0, 0, 255), 10, LINE_8);//在圖片上顯示文本
	namedWindow("輸出窗口", 0);
	resizeWindow("輸出窗口", 600, 600);
	imshow("輸出窗口", SrcImage);
	if (choice != 1) { //如果檢測(cè)視頻或者攝像頭,就延時(shí)1ms,如果檢測(cè)圖片,就停留在當(dāng)前幀
		waitKey(1);
	}
	else if (choice == 1) {
		waitKey(0);
	}
}
 
void GetCamera(int choice) {
 
	Mat frame;
	VideoCapture capture(0);//讀取視攝像頭實(shí)時(shí)畫面數(shù)據(jù),0默認(rèn)是筆記本的攝像頭;如果是外接攝像頭,這里改為1
 
	while (true)
	{
		capture >> frame;            //讀取當(dāng)前幀
		GetPicture(frame,choice);
		int key = waitKey(10);
		if (key == 32) {
			break;
		}
			
	}
	cout << "圖像中檢測(cè)過的輪廓中,最大距離為:" << MaxDistance << "cm" << endl;
	cout << "圖像中檢測(cè)過的輪廓中,最小距離為:" << MinDistance << "cm" << endl;
	capture.release();     //釋放攝像頭資源
	destroyAllWindows();   //釋放全部窗口
 
}
 
void GetVideo(int choice) {
	VideoCapture capture("視頻的絕對(duì)路徑.mp4");
 
	Mat frame;
 
	if (capture.isOpened())  //判斷視頻是否成功打開
	{
		//capture.grab() 從視頻文件或捕獲設(shè)備中抓取下一個(gè)幀
		while (capture.grab()) {
			capture >> frame;
			GetPicture(frame,choice);
			waitKey(1);
			/*int key = waitKey(10);
			if (key == 32) {
				waitKey(0);
			}
			if (key == 27) {
				break;
			}*/
		}
		
	}
	cout << "圖像中最大距離為:" << MaxDistance << "cm" << endl;
	cout << "圖像中最小距離為:" << MinDistance << "cm" << endl;
	waitKey();
}
 
double GetTheDistanceToCamera(double KnownWidth, double FocalLength, double PerWidth)
{
	return (KnownWidth * FocalLength) / PerWidth; //計(jì)算目標(biāo)到相機(jī)的距離   KnownWidth-為已知的目標(biāo)的寬度  FocalLength-焦距   PerWidth-圖像中寬度的像素?cái)?shù)
}
 
RotatedRect FindMarker(Mat& SrcImage)//畫出圖形的邊界并返回最小外接矩形
{
	Mat GrayImage;
	cvtColor(SrcImage, GrayImage, COLOR_BGR2GRAY);//將SrcImage復(fù)制給GrayImage
 
	Mat GaussImage;
	//將GrayImage通過高斯濾波處理后存放到GaussImage中
	GaussianBlur(GrayImage, GaussImage, Size(3, 7), 3); //高斯濾波,對(duì)圖像進(jìn)行濾波操作(平滑操作、過濾操作,去噪操作)
 
	Mat EdgeImage;
	Canny(GaussImage, EdgeImage, 100, 200);//邊緣檢測(cè)
	
/*這段代碼可省略,只是用來看效果。
	namedWindow("復(fù)制圖", 0);
	resizeWindow("復(fù)制圖", 600, 600);
	imshow("復(fù)制圖", GrayImage);
	namedWindow("高斯濾波處理", 0);
	resizeWindow("高斯濾波處理", 600, 600);
	imshow("高斯濾波處理", GaussImage);
	namedWindow("邊緣檢測(cè)處理", 0);
	resizeWindow("邊緣檢測(cè)處理", 600, 600);
	imshow("邊緣檢測(cè)處理", EdgeImage);
*/
	vector<vector<Point>> Contours;
	vector<Vec4i> Hierarchy;
	findContours(EdgeImage.clone(), Contours, Hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE /*,Point(10,20)*/);//檢測(cè)物體輪廓
	double Area = -1;
	int Index = -1;
	for (int i = 0; i < Contours.size(); i++)//得到最大的輪廓然后畫出來,其實(shí)是一個(gè)點(diǎn)集
	{
		if (contourArea(Contours[i]) > Area)
		{
			Area = contourArea(Contours[i]);
			Index = i;
		}
	}
	//第三個(gè)參數(shù)為-1的時(shí)候就畫出全部輪廓
	drawContours(SrcImage, Contours, -1, Scalar(0, 0, 255), 10, LINE_8);//畫出物體的輪廓
 
	RotatedRect Rorect;
	Rorect = minAreaRect(Contours[Index]);  //得到被測(cè)物的最小外接矩形
	return Rorect;
}
 
double CalculateFocalDistance(Mat& Image)//計(jì)算拍照相機(jī)的焦距
{
	RotatedRect Marker;
	Marker = FindMarker(Image);
	double FocalLength = 0.0;
	double FocalWide = 0.0;
	FocalLength = (Marker.size.height * KNOWN_DISTANCE) / KNOWN_WIDTH;  //計(jì)算焦距單位為圖像像素  依據(jù)公式: F=(P*D)/W   F-焦距   D-距離   P-像素寬度   W-目標(biāo)的真實(shí)寬度(單位英寸)
	FocalWide = (Marker.size.width * KNOWN_DISTANCE) / KNOWN_HEIGHT;
	cout << "標(biāo)定焦距:" << FocalLength << endl;
	cout << "標(biāo)定焦距:" << FocalLength << endl;
	return FocalLength;
	//1857.71
}

有關(guān)圖像的算法都是已經(jīng)封裝好了改參數(shù)直接用就行了,沒有涉及到什么需要自己寫的高難度算法。

下面還有一些比較各個(gè)邊緣檢測(cè)效果的算法代碼:

玩玩就行,原理我也不清楚,只會(huì)用現(xiàn)成的。

#include"opencv2/opencv.hpp"
using namespace cv;
using namespace std;
 
void main()
{
	//顯示原圖像
	Mat image = imread("C:/Users/蔣林宏/Desktop/圖片/240A.jpg");
	namedWindow("原圖",0);
	resizeWindow("原圖", 600, 600);
	imshow("原圖", image);
 
	//canny邊緣檢測(cè)的簡(jiǎn)單用法
	Mat result;
	Canny(image, result, 150, 70);
 
	namedWindow("canny邊緣檢測(cè)后的圖像",0);
	resizeWindow("canny邊緣檢測(cè)后的圖像", 600, 600);
	imshow("canny邊緣檢測(cè)后的圖像", result);
 
	//高階的canny用法,轉(zhuǎn)成灰度圖,降噪,用canny,最后將得到的邊緣作為掩碼,拷貝原圖到效果圖上,得到彩色邊緣圖
	Mat grayimage, edge;
	cvtColor(image, grayimage, COLOR_BGR2GRAY);
	boxFilter(grayimage, edge, -1, Size(3, 3));
	Canny(edge, edge, 150, 70);
	Mat dst;
	dst = Scalar::all(123);
	image.copyTo(dst, edge);
	
	namedWindow("canny高階邊緣檢測(cè)后的圖像",0);
	resizeWindow("canny高階邊緣檢測(cè)后的圖像", 600, 600);
	imshow("canny高階邊緣檢測(cè)后的圖像", dst);
 
	//sobel算子邊緣檢測(cè)
	Mat x_result, y_result;
	Sobel(image, x_result, 0, 1, 0);
	Sobel(image, y_result, 0, 0, 1);
	addWeighted(x_result, 0.5, y_result, 0.5, 0, result);
 
	/*imshow("sobel邊緣檢測(cè)后x軸的圖像", x_result);
	imshow("sobel邊緣檢測(cè)后y軸的圖像", y_result);*/
	namedWindow("sobel邊緣檢測(cè)后的圖像",0);
	resizeWindow("sobel邊緣檢測(cè)后的圖像", 600, 600);
	imshow("sobel邊緣檢測(cè)后的圖像", result);
 
	//laplacian邊緣檢測(cè)
	Laplacian(image, result, 0);
	namedWindow("laplacian邊緣檢測(cè)后的圖像",0);
	resizeWindow("laplacian邊緣檢測(cè)后的圖像", 600, 600);
	imshow("laplacian邊緣檢測(cè)后的圖像", result);
 
	//scharr濾波器
	boxFilter(image, image, -1, Size(3, 3));
	Scharr(image, x_result, 0, 1, 0);
	Scharr(image, x_result, 0, 0, 1);
	addWeighted(x_result, 0.5, y_result, 0.5, 0, result);
	namedWindow("scharr邊緣檢測(cè)后的圖像",0);
	resizeWindow("scharr邊緣檢測(cè)后的圖像", 600, 600);
	imshow("scharr邊緣檢測(cè)后的圖像", result);
	waitKey();
}

效果:

說實(shí)話有點(diǎn)陰森。

到此這篇關(guān)于C++利用opencv實(shí)現(xiàn)單目測(cè)距的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)C++ opencv單目測(cè)距內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實(shí)現(xiàn)景區(qū)信息管理系統(tǒng)

    C++實(shí)現(xiàn)景區(qū)信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)景區(qū)信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C語言實(shí)現(xiàn)掃雷游戲源代碼

    C語言實(shí)現(xiàn)掃雷游戲源代碼

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)掃雷游戲源代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • 如何寫出優(yōu)美的C語言代碼

    如何寫出優(yōu)美的C語言代碼

    今天小編就為大家分享一篇關(guān)于如何寫出優(yōu)美的C語言代碼,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • C++實(shí)現(xiàn)選擇性排序(SelectionSort)

    C++實(shí)現(xiàn)選擇性排序(SelectionSort)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)選擇性排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C++實(shí)現(xiàn)求動(dòng)態(tài)矩陣各元素的和

    C++實(shí)現(xiàn)求動(dòng)態(tài)矩陣各元素的和

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)求動(dòng)態(tài)矩陣各元素的和,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C++中字符串查找操作的兩則實(shí)例分享

    C++中字符串查找操作的兩則實(shí)例分享

    這篇文章主要介紹了C++中字符串的查找操作的兩則實(shí)例分享,分別是找到第一個(gè)只出現(xiàn)一次的字符以及找出連續(xù)最長的數(shù)字串的方法,需要的朋友可以參考下
    2016-02-02
  • OPENCV批量讀取圖片實(shí)現(xiàn)方法

    OPENCV批量讀取圖片實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄狾PENCV批量讀取圖片實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的?,F(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • opencv利用視頻的前n幀求平均圖像

    opencv利用視頻的前n幀求平均圖像

    這篇文章主要為大家詳細(xì)介紹了opencv利用視頻的前n幀求平均圖像,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C/C++中時(shí)間庫函數(shù)的使用詳解

    C/C++中時(shí)間庫函數(shù)的使用詳解

    這篇文章主要為大家詳細(xì)介紹了C/C++中的時(shí)間相關(guān)知識(shí)總結(jié),例如時(shí)間庫函數(shù)的使用以及獲取本地時(shí)間的不同方法,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2022-11-11
  • Qt 使用 canon edsdk 實(shí)現(xiàn)實(shí)時(shí)預(yù)覽的示例代碼

    Qt 使用 canon edsdk 實(shí)現(xiàn)實(shí)時(shí)預(yù)覽的示例代碼

    這篇文章主要介紹了Qt 使用 canon edsdk 實(shí)現(xiàn)實(shí)時(shí)預(yù)覽的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評(píng)論

连城县| 海淀区| 揭阳市| 鲁山县| 楚雄市| 徐闻县| 丰城市| 定兴县| 城市| 麻江县| 宁海县| 吉林省| 台安县| 九江县| 贵阳市| 永年县| 芮城县| 丹阳市| 临海市| 松滋市| 璧山县| 丹江口市| 济阳县| 商水县| 宽城| 岳阳市| 兴文县| 东明县| 梁河县| 昌邑市| 焉耆| 若羌县| 宁津县| 阿合奇县| 吴桥县| 德格县| 公安县| 泸定县| 怀宁县| 贵阳市| 阿坝|