当前位置:首页 > 英文周记 > 正文内容

bruteforce算法「bruteforce算法图解」

更新时间:2026-07-19 21:06:43 周记网4年前 (2023-01-26)英文周记115

什么是Brutal Force算法

其实叫brute

bruteforce算法「bruteforce算法图解」

force了,LZ别拍我xD。

就像楼上说的,就是暴力算法。

枚举所有可能的

排列组合

然后找到最优化的,或者理想的结果。

虽然结果是理想的,过程却不理想,

因为一般运算时间比较长。

opencv surf算法连线颜色怎么设置一样

/**

* @file SURF_Homography

* @brief SURF detector + descriptor + FLANN Matcher + FindHomography

* @author A. Huaman

*/

#include stdio.h

#include iostream

#include cv.h

#include "opencv2/core/core.hpp"

#include opencv2/opencv.hpp

#include "opencv2/features2d/features2d.hpp"

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/calib3d/calib3d.hpp"

#include "opencv2/nonfree/features2d.hpp"

#include opencv2/imgproc/imgproc.hpp

#include opencv2/nonfree/nonfree.hpp

using namespace cv;

using namespace std;

#ifdef _DEBUG

#pragma comment (lib, "opencv_calib3d246d.lib")

#pragma comment (lib, "opencv_contrib246d.lib")

#pragma comment (lib,"opencv_imgproc246d.lib")

#pragma comment (lib, "opencv_core246d.lib")

#pragma comment (lib, "opencv_features2d246d.lib")

#pragma comment (lib, "opencv_flann246d.lib")

#pragma comment (lib, "opencv_gpu246d.lib")

#pragma comment (lib, "opencv_highgui246d.lib")

#pragma comment (lib, "opencv_legacy246d.lib")

#pragma comment (lib, "opencv_ml246d.lib")

#pragma comment (lib, "opencv_objdetect246d.lib")

#pragma comment (lib, "opencv_ts246d.lib")

#pragma comment (lib, "opencv_video246d.lib")

#pragma comment (lib, "opencv_nonfree246d.lib")

#else

#pragma comment (lib, "opencv_calib3d246.lib")

#pragma comment (lib, "opencv_contrib246.lib")

#pragma comment (lib, "opencv_imgproc246.lib")

#pragma comment (lib, "opencv_core246.lib")

#pragma comment (lib, "opencv_features2d246.lib")

#pragma comment (lib, "opencv_flann246.lib")

#pragma comment (lib, "opencv_gpu246.lib")

#pragma comment (lib, "opencv_highgui246.lib")

#pragma comment (lib, "opencv_legacy246.lib")

#pragma comment (lib, "opencv_ml246.lib")

#pragma comment (lib, "opencv_objdetect246.lib")

#pragma comment (lib, "opencv_ts246.lib")

#pragma comment (lib, "opencv_video246.lib")

#pragma comment (lib, "opencv_nonfree246.lib")

#endif

int main()

{

initModule_nonfree();//初始化模块,使用SIFT或SURF时用到

PtrFeatureDetector detector = FeatureDetector::create( "SURF" );//创建SIFT特征检测器,可改成SURF/ORB

PtrDescriptorExtractor descriptor_extractor = DescriptorExtractor::create( "SURF" );//创建特征向量生成器,可改成SURF/ORB

PtrDescriptorMatcher descriptor_matcher = DescriptorMatcher::create( "BruteForce" );//创建特征匹配器

if( detector.empty() || descriptor_extractor.empty() )

cout"fail to create detector!";

//读入图像

Mat img1 = imread("1.jpg");

Mat img2 = imread("2.jpg");

//特征点检测

double t = getTickCount();//当前滴答数

vectorKeyPoint m_LeftKey,m_RightKey;

detector-detect( img1, m_LeftKey );//检测img1中的SIFT特征点,存储到m_LeftKey中

detector-detect( img2, m_RightKey );

cout"图像1特征点个数:"m_LeftKey.size()endl;

cout"图像2特征点个数:"m_RightKey.size()endl;

//根据特征点计算特征描述子矩阵,即特征向量矩阵

Mat descriptors1,descriptors2;

descriptor_extractor-compute( img1, m_LeftKey, descriptors1 );

descriptor_extractor-compute( img2, m_RightKey, descriptors2 );

t = ((double)getTickCount() - t)/getTickFrequency();

cout"SIFT算法用时:"t"秒"endl;

cout"图像1特征描述矩阵大小:"descriptors1.size()

",特征向量个数:"descriptors1.rows",维数:"descriptors1.colsendl;

cout"图像2特征描述矩阵大小:"descriptors2.size()

",特征向量个数:"descriptors2.rows",维数:"descriptors2.colsendl;

//画出特征点

Mat img_m_LeftKey,img_m_RightKey;

drawKeypoints(img1,m_LeftKey,img_m_LeftKey,Scalar::all(-1),0);

drawKeypoints(img2,m_RightKey,img_m_RightKey,Scalar::all(-1),0);

//imshow("Src1",img_m_LeftKey);

//imshow("Src2",img_m_RightKey);

//特征匹配

vectorDMatch matches;//匹配结果

descriptor_matcher-match( descriptors1, descriptors2, matches );//匹配两个图像的特征矩阵

cout"Match个数:"matches.size()endl;

//计算匹配结果中距离的最大和最小值

//距离是指两个特征向量间的欧式距离,表明两个特征的差异,值越小表明两个特征点越接近

double max_dist = 0;

double min_dist = 100;

for(int i=0; imatches.size(); i++)

{

double dist = matches[i].distance;

if(dist min_dist) min_dist = dist;

if(dist max_dist) max_dist = dist;

}

cout"最大距离:"max_distendl;

cout"最小距离:"min_distendl;

//筛选出较好的匹配点

vectorDMatch goodMatches;

for(int i=0; imatches.size(); i++)

{

if(matches[i].distance 0.2 * max_dist)

{

goodMatches.push_back(matches[i]);

}

}

cout"goodMatch个数:"goodMatches.size()endl;

//画出匹配结果

Mat img_matches;

//红色连接的是匹配的特征点对,绿色是未匹配的特征点

drawMatches(img1,m_LeftKey,img2,m_RightKey,goodMatches,img_matches,

Scalar::all(-1)/*CV_RGB(255,0,0)*/,CV_RGB(0,255,0),Mat(),2);

imshow("MatchSIFT",img_matches);

IplImage result=img_matches;

waitKey(0);

//RANSAC匹配过程

vectorDMatch m_Matches=goodMatches;

// 分配空间

int ptCount = (int)m_Matches.size();

Mat p1(ptCount, 2, CV_32F);

Mat p2(ptCount, 2, CV_32F);

// 把Keypoint转换为Mat

Point2f pt;

for (int i=0; iptCount; i++)

{

pt = m_LeftKey[m_Matches[i].queryIdx].pt;

p1.atfloat(i, 0) = pt.x;

p1.atfloat(i, 1) = pt.y;

pt = m_RightKey[m_Matches[i].trainIdx].pt;

p2.atfloat(i, 0) = pt.x;

p2.atfloat(i, 1) = pt.y;

}

// 用RANSAC方法计算F

Mat m_Fundamental;

vectoruchar m_RANSACStatus; // 这个变量用于存储RANSAC后每个点的状态

findFundamentalMat(p1, p2, m_RANSACStatus, FM_RANSAC);

// 计算野点个数

int OutlinerCount = 0;

for (int i=0; iptCount; i++)

{

if (m_RANSACStatus[i] == 0) // 状态为0表示野点

{

OutlinerCount++;

}

}

int InlinerCount = ptCount - OutlinerCount; // 计算内点

cout"内点数为:"InlinerCountendl;

// 这三个变量用于保存内点和匹配关系

vectorPoint2f m_LeftInlier;

vectorPoint2f m_RightInlier;

vectorDMatch m_InlierMatches;

m_InlierMatches.resize(InlinerCount);

m_LeftInlier.resize(InlinerCount);

m_RightInlier.resize(InlinerCount);

InlinerCount=0;

float inlier_minRx=img1.cols; //用于存储内点中右图最小横坐标,以便后续融合

for (int i=0; iptCount; i++)

{

if (m_RANSACStatus[i] != 0)

{

m_LeftInlier[InlinerCount].x = p1.atfloat(i, 0);

m_LeftInlier[InlinerCount].y = p1.atfloat(i, 1);

m_RightInlier[InlinerCount].x = p2.atfloat(i, 0);

m_RightInlier[InlinerCount].y = p2.atfloat(i, 1);

m_InlierMatches[InlinerCount].queryIdx = InlinerCount;

m_InlierMatches[InlinerCount].trainIdx = InlinerCount;

if(m_RightInlier[InlinerCount].xinlier_minRx) inlier_minRx=m_RightInlier[InlinerCount].x; //存储内点中右图最小横坐标

InlinerCount++;

}

}

// 把内点转换为drawMatches可以使用的格式

vectorKeyPoint key1(InlinerCount);

vectorKeyPoint key2(InlinerCount);

KeyPoint::convert(m_LeftInlier, key1);

KeyPoint::convert(m_RightInlier, key2);

// 显示计算F过后的内点匹配

Mat OutImage;

drawMatches(img1, key1, img2, key2, m_InlierMatches, OutImage);

cvNamedWindow( "Match features", 1);

cvShowImage("Match features", IplImage(OutImage));

waitKey(0);

cvDestroyAllWindows();

//矩阵H用以存储RANSAC得到的单应矩阵

Mat H = findHomography( m_LeftInlier, m_RightInlier, RANSAC );

//存储左图四角,及其变换到右图位置

std::vectorPoint2f obj_corners(4);

obj_corners[0] = Point(0,0); obj_corners[1] = Point( img1.cols, 0 );

obj_corners[2] = Point( img1.cols, img1.rows ); obj_corners[3] = Point( 0, img1.rows );

std::vectorPoint2f scene_corners(4);

perspectiveTransform( obj_corners, scene_corners, H);

//画出变换后图像位置

Point2f offset( (float)img1.cols, 0);

line( OutImage, scene_corners[0]+offset, scene_corners[1]+offset, Scalar( 0, 255, 0), 4 );

line( OutImage, scene_corners[1]+offset, scene_corners[2]+offset, Scalar( 0, 255, 0), 4 );

line( OutImage, scene_corners[2]+offset, scene_corners[3]+offset, Scalar( 0, 255, 0), 4 );

line( OutImage, scene_corners[3]+offset, scene_corners[0]+offset, Scalar( 0, 255, 0), 4 );

imshow( "Good Matches Object detection", OutImage );

waitKey(0);

imwrite("warp_position.jpg",OutImage);

int drift = scene_corners[1].x; //储存偏移量

VR如何渲染动画?

在vray3.0及之前的时代,使用vray渲染动画是一件比较繁琐的工作。又是分层渲染又是隔帧预渲染光子,又或者是逐帧预渲染光子。甚至关掉GI单独GI设置等等,这都是为了避免动画渲染的闪烁或者斑点。平衡渲染质量与渲染时间。

当vray3.6及4.0发布之后,使用vray进行动画渲染变得非常简单。2020年vray5.0发布,至今天vray已经更新到5.1。渲染动画在速度上已经有了很快的提升。vray多年GI诟病已经不让我烦恼。

下面就介绍一下vray官方给出的动画渲染设置。

传统上(祖传闪烁),vray动画序列的渲染可能会在帧间产生不想要的闪烁,也被称为“bubbling冒泡”或“boiling沸腾”。这是因为低频噪波在帧间发生变化。

其实V-RayNext(也就是vray4.0) 时候解已经决这些问题,只有两个调整的默认设置:Light Cache Subdivs,,和Retrace数值。虽然推荐的设置在大多数情况下都是适用的(比如室内,室外,环境,包拍摄,特效模拟),但我们建议您在提交到最终的序列渲染之前,还是要渲染具有代表性的帧来测试一下有无问题。(译者:这是免责声明啊)

如果仍然存在一些视觉伪影(诸如噪点、斑点),继续以小数值增加这两个设置,直到它们被解决。接下来就是讲到如何设置。

1.1所有的设置都是在V-Ray默认渲染设置下进行的。可以通过更改到另一个渲染引擎,然后再更改回V-Ray,这就重置vray设置了。这是大前提,如果打开旧版本vray的文件就需要先重置渲染器。

1.2设置图像采样器为“Bucket.”。点击渲染设置 V-Ray标签图像采样器(抗锯齿)类型“Bucket.”。这是最终渲染的首选采样类型,因为它比渐进式稍微快一些,并且与一些辅助技术一起工作得更全面。译者:意思就是“Bucket”模式bug更少。

1.3选择最适合您需要的噪声阈值。0.005的值将去除可见的噪波,而不用渲染后去噪(译者:就不用加降噪了)。要比较这两个值,请查看上面示例中的默认值0.01和0.005之间的差异。

1.4。进入GI选项卡的Light Cache设置,将subdiv设置为3000。增加光缓存子divs确保了光缓存被很好的采样,并且在帧之间是稳定的。与渲染实际帧相比,更高的subdiv对渲染时间的影响可以忽略不计,所以这是一个良好的常规做法,没有任何特别的缺点。

请注意,光缓存的计算方法需要是“每帧”(默认),而不是路径驱动的方法,如“摄像机路径”。

总结:Vray4.0后,官方推荐的动画渲染设置已经不分运动物体和静止物体。动画的渲染设置,在默认参数前提下,仅仅需要调整两个位置:

1.图像采样器使用Bucket.noisethreshold设置为 0.005就不需要降噪了。默认的话也可以添加降噪器即可。

2. GI全局光照栏的设置

当然动画渲染时间普遍都是偏长的,一般公司都是找一些渲染农场来完成项目的渲染工作,但是好用的一般都贵,稍微实惠点的就不好用,又慢又排队,有兴趣的可以去体验一下这个农场,叫渲染101,目前来说是最好用,效率最高的农场,速度快也不排队,而且最重要的是价格非常低

opencv 中自带的模板匹配算法出处

方法如下:

使用OPENCV下SIFT库做图像匹配的例程

// opencv_empty_proj.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include opencv2/opencv.hpp

#include opencv2/features2d/features2d.hpp

#includeopencv2/nonfree/nonfree.hpp

#includeopencv2/legacy/legacy.hpp

#includevector

using namespace std;

using namespace cv;

int _tmain(int argc, _TCHAR* argv[])

{

const char* imagename = "img.jpg";

//从文件中读入图像

Mat img = imread(imagename);

Mat img2=imread("img2.jpg");

//如果读入图像失败

if(img.empty())

{

fprintf(stderr, "Can not load image %s\n", imagename);

return -1;

}

if(img2.empty())

{

fprintf(stderr, "Can not load image %s\n", imagename);

return -1;

}

//显示图像

imshow("image before", img);

imshow("image2 before",img2);

//sift特征检测

SiftFeatureDetector siftdtc;

vectorKeyPointkp1,kp2;

siftdtc.detect(img,kp1);

Mat outimg1;

drawKeypoints(img,kp1,outimg1);

imshow("image1 keypoints",outimg1);

KeyPoint kp;

vectorKeyPoint::iterator itvc;

for(itvc=kp1.begin();itvc!=kp1.end();itvc++)

{

cout"angle:"itvc-angle"\t"itvc-class_id"\t"itvc-octave"\t"itvc-pt"\t"itvc-responseendl;

}

siftdtc.detect(img2,kp2);

Mat outimg2;

drawKeypoints(img2,kp2,outimg2);

imshow("image2 keypoints",outimg2);

SiftDescriptorExtractor extractor;

Mat descriptor1,descriptor2;

BruteForceMatcherL2float matcher;

vectorDMatch matches;

Mat img_matches;

extractor.compute(img,kp1,descriptor1);

extractor.compute(img2,kp2,descriptor2);

imshow("desc",descriptor1);

coutendldescriptor1endl;

matcher.match(descriptor1,descriptor2,matches);

drawMatches(img,kp1,img2,kp2,matches,img_matches);

imshow("matches",img_matches);

//此函数等待按键,按键盘任意键就返回

waitKey();

return 0;

}

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。