OpenCV CUDA对象检测

基于颜色的对象检测

对象具有许多全局特征,如颜色和形状,将对象作为一个整体描述。这些特征可用于检测对象并以一系列帧跟踪它。在本节中,我们将使用颜色作为特征来检测具有特定颜色的对象。当要检测的对象具有特定颜色且该颜色与背景颜色不同时此方法很有用。如果对象和背景具有相同的颜色,则此方法将检测失败。本节中,我们将尝试使用OpenCV和CUDA从网络摄像机流中检测任意蓝色对象。

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

int main(int argc, char** argv)
{
	cv::VideoCapture cap(0); //capture the video from web cam
	// if webcam is not available then exit the program
	if (!cap.isOpened())
	{
		std::cout << "Cannot open the web cam" << std::endl;
		return -1;
	}
	while (true)
	{
		cv::Mat frame;
		// read a new frame from webcam
		bool flag = cap.read(frame);
		if (!flag)
		{
			std::cout << "Cannot read a frame from webcam" << std::endl;
			break;
		}

		cv::cuda::GpuMat d_frame, d_frame_hsv, d_intermediate, d_result;
		cv::cuda::GpuMat d_frame_shsv[3];
		cv::cuda::GpuMat d_thresc[3];
		cv::Mat h_result;
		d_frame.upload(frame);
		//Transform image to HSV
		cv::cuda::cvtColor(d_frame, d_frame_hsv, cv::COLOR_BGR2HSV);

		//Split HSV 3 channels
		cv::cuda::split(d_frame_hsv, d_frame_shsv);

		//Threshold HSV channels
		cv::cuda::threshold(d_frame_shsv[0], d_thresc[0], 110, 130, cv::THRESH_BINARY);
		cv::cuda::threshold(d_frame_shsv[1], d_thresc[1], 50, 255, cv::THRESH_BINARY);
		cv::cuda::threshold(d_frame_shsv[2], d_thresc[2], 50, 255, cv::THRESH_BINARY);

		//Bitwise AND the channels
		cv::cuda::bitwise_and(d_thresc[0], d_thresc[1], d_intermediate);
		cv::cuda::bitwise_and(d_intermediate, d_thresc[2], d_result);

		d_result.download(h_result);
		imshow("Thresholded Image", h_result);
		imshow("Original", frame);

		if (cv::waitKey(1) == 'q')
		{
			break;
		}
	}
	return 0;
}

基于形状的对象检测

Canny边缘检测

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

int main()
{
    cv::Mat h_image = cv::imread("images/drawing.JPG", 0);
    if (h_image.empty())
    {
        std::cout << "can not open image"<< std::endl;
        return -1;
    }
    
	cv::cuda::GpuMat d_edge,d_image;
	cv::Mat h_edge;
	d_image.upload(h_image);
	cv::Ptr<cv::cuda::CannyEdgeDetector> canny_edge = cv::cuda::createCannyEdgeDetector(2.0, 100.0, 3, false);
	canny_edge->detect(d_image, d_edge);
    d_edge.download(h_edge);
	cv::imshow("source", h_image);
	cv::imshow("detected edges", h_edge);
	cv::waitKey(0);

    return 0;
}

Hough变换直线检测

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

int main()
{
    cv::Mat h_image = cv::imread("images/drawing.JPG",0);
    if (h_image.empty())
    {
        std::cout << "can not open image"<< std::endl;
        return -1;
    }

	cv::Mat h_edge;
    cv::Canny(h_image, h_edge, 100, 200, 3);

	cv::Mat h_imagec;
    cv::cvtColor(h_edge, h_imagec, cv::COLOR_GRAY2BGR);
	cv::Mat h_imageg = h_imagec.clone();
	std::vector<cv::Vec4i> h_lines;
    {
        const int64 start = cv::getTickCount();
        HoughLinesP(h_edge, h_lines, 1, CV_PI / 180, 50, 60, 5);
        const double time_elapsed = (cv::getTickCount() - start) / cv::getTickFrequency();
		std::cout << "CPU Time : " << time_elapsed * 1000 << " ms" << std::endl;
		std::cout << "CPU FPS : " << (1/time_elapsed) << std::endl;
    }

    for (size_t i = 0; i < h_lines.size(); ++i)
    {
		cv::Vec4i line_point = h_lines[i];
		cv::line(h_imagec, cv::Point(line_point[0], line_point[1]), cv::Point(line_point[2], line_point[3]), cv::Scalar(0, 0, 255), 2, cv::LINE_AA);
    }

	cv::cuda::GpuMat d_edge, d_lines;
	d_edge.upload(h_edge);
    {
		const int64 start = cv::getTickCount();
		cv::Ptr<cv::cuda::HoughSegmentDetector> hough = cv::cuda::createHoughSegmentDetector(1.0f, (float) (CV_PI / 180.0f), 50, 5);
        hough->detect(d_edge, d_lines);

        const double time_elapsed = (cv::getTickCount() - start) / cv::getTickFrequency();
		std::cout << "GPU Time : " << time_elapsed * 1000 << " ms" << std::endl;
		std::cout << "GPU FPS : " << (1/time_elapsed) << std::endl;
    }
	std::vector<cv::Vec4i> lines_g;
    if (!d_lines.empty())
    {
        lines_g.resize(d_lines.cols);
		cv::Mat h_lines(1, d_lines.cols, CV_32SC4, &lines_g[0]);
        d_lines.download(h_lines);
    }
    for (size_t i = 0; i < lines_g.size(); ++i)
    {
		cv::Vec4i line_point = lines_g[i];
		cv::line(h_imageg, cv::Point(line_point[0], line_point[1]), cv::Point(line_point[2], line_point[3]), cv::Scalar(0, 0, 255), 2, cv::LINE_AA);
    }

	cv::imshow("source", h_image);
	cv::imshow("detected lines [CPU]", h_imagec);
	cv::imshow("detected lines [GPU]", h_imageg);
	cv::imwrite("hough_source.png", h_image);
	cv::imwrite("hough_cpu_line.png", h_imagec);
	cv::imwrite("hough_gpu_line.png", h_imageg);
	cv::waitKey(0);

    return 0;
}

Hough变换圆检测

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

int main(int argc, char** argv)
{
	cv::Mat h_image = cv::imread("images/eight.tif", 1);
	cv::Mat h_gray;
	cv::cvtColor(h_image, h_gray, cv::COLOR_BGR2GRAY);
	cv::cuda::GpuMat d_gray, d_result;
	std::vector<cv::Vec3f> d_Circles;
	cv::medianBlur(h_gray, h_gray, 5);
	cv::Ptr<cv::cuda::HoughCirclesDetector> detector = cv::cuda::createHoughCirclesDetector(1, 100, 122, 50, 1, std::max(h_image.size().width, h_image.size().height));
	d_gray.upload(h_gray);
	detector->detect(d_gray, d_result);
	d_Circles.resize(d_result.size().width);

	if (!d_Circles.empty())
		d_result.row(0).download(cv::Mat(d_Circles).reshape(3, 1));
	std::cout << "No of circles: " << d_Circles.size() << std::endl;
	for (size_t i = 0; i < d_Circles.size(); i++)
	{
		cv::Vec3i cir = d_Circles[i];
		cv::circle(h_image, cv::Point(cir[0], cir[1]), cir[2], cv::Scalar(255, 0, 0), 2, cv::LINE_AA);
	}
	cv::imshow("detected circles", h_image);
	cv::waitKey(0);

	return 0;
}

关键点检测和描述符

FAST关键点

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

int main()
{
	cv::Mat h_image = cv::imread("images/drawing.JPG", 0);

	//Detect the keypoints using FAST Detector
	cv::Ptr<cv::cuda::FastFeatureDetector> detector = cv::cuda::FastFeatureDetector::create(100, true, 2);
	std::vector<cv::KeyPoint> keypoints;
	cv::cuda::GpuMat d_image;
	d_image.upload(h_image);
	detector->detect(d_image, keypoints);
	cv::drawKeypoints(h_image, keypoints, h_image);

	//Show detected keypoints
	cv::imshow("Final Result", h_image);
	cv::waitKey(0);
	return 0;
}

ORB特征检测

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

int main()
{
	cv::Mat h_image = cv::imread("images/drawing.JPG", 0);
	cv::Ptr<cv::cuda::ORB> detector = cv::cuda::ORB::create();
	std::vector<cv::KeyPoint> keypoints;
	cv::cuda::GpuMat d_image;
	d_image.upload(h_image);
	detector->detect(d_image, keypoints);
	cv::drawKeypoints(h_image, keypoints, h_image);
	cv::imshow("Final Result", h_image);
	cv::waitKey(0);
	return 0;
}

SURF特征检测

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/cudafeatures2d.hpp>
#include <opencv2/xfeatures2d/cuda.hpp>

int main(int argc, char** argv)
{
	cv::Mat h_object_image = cv::imread("images/object1.jpg", 0);
	cv::Mat h_scene_image = cv::imread("images/scene1.jpg", 0);

	cv::cuda::GpuMat d_object_image;
	cv::cuda::GpuMat d_scene_image;

	cv::cuda::GpuMat d_keypoints_scene, d_keypoints_object;
	std::vector<cv::KeyPoint> h_keypoints_scene, h_keypoints_object;
	cv::cuda::GpuMat d_descriptors_scene, d_descriptors_object;

	d_object_image.upload(h_object_image);
	d_scene_image.upload(h_scene_image);

	cv::cuda::SURF_CUDA surf(100);
	surf(d_object_image, cv::cuda::GpuMat(), d_keypoints_object, d_descriptors_object);
	surf(d_scene_image, cv::cuda::GpuMat(), d_keypoints_scene, d_descriptors_scene);

	cv::Ptr<cv::cuda::DescriptorMatcher> matcher = cv::cuda::DescriptorMatcher::createBFMatcher();
	std::vector<std::vector<cv::DMatch>> d_matches;
	matcher->knnMatch(d_descriptors_object, d_descriptors_scene, d_matches, 2);

	surf.downloadKeypoints(d_keypoints_scene, h_keypoints_scene);
	surf.downloadKeypoints(d_keypoints_object, h_keypoints_object);

	std::vector<cv::DMatch> good_matches;
	for (int k = 0; k < std::min(h_keypoints_object.size() - 1, d_matches.size()); k++)
	{
		if ((d_matches[k][0].distance < 0.6 * (d_matches[k][1].distance)) && ((int)d_matches[k].size() <= 2 && (int)d_matches[k].size() > 0))
		{
			good_matches.push_back(d_matches[k][0]);
		}
	}
	std::cout << "size:" << good_matches.size();
	cv::Mat h_image_result;
	cv::drawMatches(h_object_image, h_keypoints_object, h_scene_image, h_keypoints_scene,
		good_matches, h_image_result, cv::Scalar::all(-1), cv::Scalar::all(-1),
		std::vector<char>(), cv::DrawMatchesFlags::DEFAULT);

	std::vector<cv::Point2f> object;
	std::vector<cv::Point2f> scene;
	for (int i = 0; i < good_matches.size(); i++) 
	{
		object.push_back(h_keypoints_object[good_matches[i].queryIdx].pt);
		scene.push_back(h_keypoints_scene[good_matches[i].trainIdx].pt);
	}
	cv::Mat Homo = cv::findHomography(object, scene, cv::RANSAC);
	std::vector<cv::Point2f> corners(4);
	std::vector<cv::Point2f> scene_corners(4);
	corners[0] = cv::Point(0, 0);
	corners[1] = cv::Point(h_object_image.cols, 0);
	corners[2] = cv::Point(h_object_image.cols, h_object_image.rows);
	corners[3] = cv::Point(0, h_object_image.rows);
	cv::perspectiveTransform(corners, scene_corners, Homo);

	cv::line(h_image_result, scene_corners[0] + cv::Point2f(h_object_image.cols, 0), scene_corners[1] + cv::Point2f(h_object_image.cols, 0), cv::Scalar(255, 0, 0), 4);
	cv::line(h_image_result, scene_corners[1] + cv::Point2f(h_object_image.cols, 0), scene_corners[2] + cv::Point2f(h_object_image.cols, 0), cv::Scalar(255, 0, 0), 4);
	cv::line(h_image_result, scene_corners[2] + cv::Point2f(h_object_image.cols, 0), scene_corners[3] + cv::Point2f(h_object_image.cols, 0), cv::Scalar(255, 0, 0), 4);
	cv::line(h_image_result, scene_corners[3] + cv::Point2f(h_object_image.cols, 0), scene_corners[0] + cv::Point2f(h_object_image.cols, 0), cv::Scalar(255, 0, 0), 4);
	cv::imshow("Good Matches & Object detection", h_image_result);
	cv::waitKey(0);
	return 0;
}

Haar级联对象检测

Haar级联人脸检测

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

int main()
{
	cv::Mat h_image = cv::imread("Chapter7//lena_color_512.tif", 0);
	cv::Ptr<cv::cuda::CascadeClassifier> cascade = cv::cuda::CascadeClassifier::create("Chapter7//haarcascade_frontalface_alt2.xml");
	cv::cuda::GpuMat d_image;
	cv::cuda::GpuMat d_buf;
	d_image.upload(h_image);
	std::cout << "No detection." << std::endl;
	cascade->detectMultiScale(d_image, d_buf);
	std::cout << "No detection." << std::endl;
	std::vector<cv::Rect> detections;
	cascade->convert(d_buf, detections);
	if (detections.empty())
		std::cout << "No detection." << std::endl;
	cv::cvtColor(h_image, h_image, cv::COLOR_GRAY2BGR);
	for (int i = 0; i < detections.size(); ++i)
	{
		cv::rectangle(h_image, detections[i], cv::Scalar(0, 255, 255), 5);
	}

	cv::imshow("Result image", h_image);
	cv::waitKey(0);
	return 0;
}

Haar级联人眼检测

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

int main()
{
	cv::Mat h_image = cv::imread("images/lena_color_512.tif", 0);
	cv::Ptr<cv::cuda::CascadeClassifier> cascade = cv::cuda::CascadeClassifier::create("Chapter7//haarcascade_eye.xml");
	cv::cuda::GpuMat d_image;
	cv::cuda::GpuMat d_buf;
	d_image.upload(h_image);
	cascade->detectMultiScale(d_image, d_buf);
	std::vector<cv::Rect> detections;
	cascade->convert(d_buf, detections);
	if (detections.empty())
		std::cout << "No detection." << std::endl;
	cv::cuda::cvtColor(h_image, h_image, cv::COLOR_GRAY2BGR);
	for (int i = 0; i < detections.size(); ++i)
	{
		rectangle(h_image, detections[i], cv::Scalar(0, 255, 255), 5);
	}
	cv::imshow("Result image", h_image);
	cv::waitKey(0);
	return 0;
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
OpenCV(开源计算机视觉库)是一个开源计算机视觉和机器学习软件库。OpenCV的构建旨在为计算机视觉应用程序提供通用的基础结构,并加速在商业产品中使用机器感知。作为BSD许可的产品,OpenCV使企业可以轻松地使用和修改代码。 该库具有2500多种优化算法,其中包括一整套经典和最新的计算机视觉和机器学习算法。这些算法可用于检测和识别人脸,识别对象,对视频中的人为行为进行分类,跟踪摄像机的运动,跟踪运动的对象,提取对象的3D模型,从立体摄像机生成3D点云,将图像拼接在一起以产生高分辨率整个场景的图像,从图像数据库中查找相似的图像,从使用闪光灯拍摄的图像中消除红眼,跟随眼睛的运动,识别风景并建立标记以将其与增强现实叠加在一起等。OpenCV拥有超过4.7万人的用户社区,下载量估计超过1800万。该库在公司,研究小组和政府机构中得到广泛使用。 除了使用该库的Google,Yahoo,Microsoft,Intel,IBM,Sony,Honda,Toyota之类的知名公司外,还有许多应用创业公司,Applied Minds,VideoSurf和Zeitera等都在广泛使用OpenCVOpenCV的部署用途包括将街景图像拼接在一起,检测以色列监视视频中的入侵,监视中国的矿山设备,帮助机器人在Willow Garage导航和拾取物体,检测欧洲游泳池溺水事故,在西班牙和纽约,在土耳其检查跑道上的碎屑,检查世界各地工厂产品上的标签,然后在日本进行快速面部识别。 它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS。OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令。 目前,正在积极开发功能齐全的CUDA和OpenCL接口。有500多种算法,而构成或支持这些算法的功能大约是其10倍。OpenCV用C ++原生编写,并具有可与STL容器无缝配合的模板化接口。
要在Python中配置OpenCV以使用CUDA加速,您需要按照以下步骤进行操作: 1. 安装CUDA驱动和CUDA工具包:首先,您需要在您的计算机上安装NVIDIA的CUDA驱动程序和CUDA工具包。您可以从NVIDIA官方网站下载并安装适用于您的系统的版本。 2. 安装OpenCVOpenCVCUDA模块:使用pip或其他包管理器安装OpenCV。确保安装的是支持CUDA的版本。例如,您可以运行以下命令来安装支持CUDAOpenCV: ``` pip install opencv-python==<your_opencv_version> ``` 请注意,在上述命令中,将`<your_opencv_version>`替换为您希望安装的OpenCV版本。 3. 配置环境变量:在您的系统环境变量中,添加以下两个变量: - `CUDA_PATH`:将其设置为您CUDA工具包的安装路径。 - `PATH`:将CUDA工具包的`bin`目录添加到`PATH`变量中。 4. 测试CUDA加速:编写一个简单的Python脚本来测试OpenCV是否成功配置了CUDA加速。以下是一个示例脚本: ```python import cv2 def main(): # 读取图像 image = cv2.imread('path_to_your_image.jpg') # 创建一个GPU加速的ORB对象 orb = cv2.cuda_ORB.create() # 将图像上传到GPU内存 gpu_image = cv2.cuda_GpuMat() gpu_image.upload(image) # 在GPU上进行特征检测 keypoints = orb.detect(gpu_image) # 从GPU内存中下载特征点 keypoints = keypoints.download() # 在图像上绘制特征点 image_with_keypoints = cv2.drawKeypoints(image, keypoints, None) # 显示图像 cv2.imshow('Image with Keypoints', image_with_keypoints) cv2.waitKey(0) cv2.destroyAllWindows() if __name__ == '__main__': main() ``` 运行上述脚本,如果您的系统正确配置了CUDA加速,您将看到一幅带有ORB特征点的图像显示在屏幕上。 请注意,上述步骤假设您已经正确安装了适用于您的系统的CUDA驱动程序和工具包。如果您遇到任何问题,请参考OpenCVCUDA的官方文档,以获取更详细的安装和配置指南。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

给算法爸爸上香

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

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

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

打赏作者

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

抵扣说明:

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

余额充值