目录
OpenCV可能是目前使用最广泛的开源图像处理工具了,尤其是在科研领域。
在读研期间进行图像拼接相关的科研工作时候,我遇到了和OpenCV相关很棘手的两个问题:
1.为什么的我的OpenCV安装不成功???
2.为什么我的OpenCV不能修改源码?
那个时候CSDN上的相关资料也不多,甚至现在关于OpenCV安装的很多问题,CSDN上说的也不算很清楚。与此同时那段时间也是自己比较艰难的一段时间,在OpenCV上花了很多时间和精力才终于解决了上述两个问题。我在此分享一下如何解决这两个问题。
本篇主要详细记录一下如何在Windows 操作系统下,搭建Visual Studio+OpenCV+OpenCV contrib的运行环境。
关于安装visual studio,最保险的方法首先去官网下载安装器:
下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux
暂时使用Community版本就好,尤其是对学生or个人用户而言。

然后安装的时候,参考第一个"参考链接"(我自己安装的时候忘记截图了啦真的是很对不起了啦,谁要是质疑我就很机车了啦):

然后只要选择"使用C++的桌面开发"就好。

然后一路默认安装就好。
本地随便建一个新项目运行:

选择“控制台应用”:

项目建立之后,点击"本地Windows调试器":

然后就可以运行输出HelloWorld了:

既然要下载源码了,我们还是去OpenCV的官网,下载最新的release版本:
截止至2022年4月4号,最新的Release版本是OpenCV – 4.5.5。我们下载Sources(后面修改源码需要用到):

下载之后解压到特定文件夹,当前case之中我解压到了E:\Downloads\opencv-4.5.5

然后我们去下载OpenCV contrib,官网链接:
GitHub - opencv/opencv_contrib: Repository for OpenCV's extra modules
Q:为什么要下载OpenCV contrib呢?
A:因为自从OpenCV 3.0之后,很多经典的算法,比如sift和surf特征点检测算法,由于专利原因,已经不包含在OpenCV的源码当中了,需要下载OpenCV contrib包才能继续使用。

OpenCV contrib的版本记得要和OpenCV版本符合哦(例如上图我们选择的是4.X版本)。还是要下载源码哦。

下载完解压,本文的路径为:E:\Downloads\opencv_contrib-4.x

之后我们还需要去下载cmake 用于编译OpenCV。
这里别下载错了下载成source了。在安装OpenCV的过程之中,我们只需要使用Cmake的gui程序图像化运行就好,不需要去管cmake的源码。

下载完解压,本文的解压地址为:E:\Downloads\cmake-3.23.0-windows-x86_64。在bin目录下运行cmake-gui.exe即可。


前置工作结束就需要开始编译OpenCV了。
1.第一步先按下图操作:

2.弹窗出来的配置,按照自己的开发环境配置即可(本文的环境是VS 2022,平台是X64平台),然后点击"Finish"即可:

3.cmake的窗口开始打印信息:

打印出来的信息中如果出现python、matlab相关的报错,例如下图,直接pass。(Python……ptsd,想到python就ptsd……想起某人爱用python造轮子……)

这一步需要等到cmake初始编译完成。
这一步很多博客都没有写清楚如何排查,导致很多新手在之后VisualStudio阶段导包的时候出错。
上一步完成之后,大部分情况下会报错。
不出意外会看到如下的报错信息。

仔细阅读之后,我们应该查看一下CMakeDownloadLog.txt。
使用Notepad++或者其他软件打开CMakeDownloadLog.txt,

有时间的同学自己阅读和翻译。我直接说一下问题:Cmake去下载相关的包没有下载下来。
所以根据红框处的信息我们需要自行下载,方法:将链接输入到浏览器,然后就会自动下载。一些链接输入到浏览器之后,显示的是文本,那么就将文本拷贝到本地并重命名,如下图的cmake文件。

这种情况,就ctrl+s保存,注意命名。

此处我不把包上传到CSDN上,因为版本更新之后还是有可能遇到同样问题,希望后续OpenCV版本更新之后,大家能自行解决问题。
另外此处的链接可能会被屏蔽,大家自行找办法下载。
下载之后将这些包拷贝到.cache文件夹下,并且需要更改包的名字(cmake下载包之后将校验的hash码重命名到了包中),下图以ippcv包为例:
下载的包原名为:
ippicv_2020_win_intel64_20191018_general.zip
复制到CmakeDownloadLog.txt中的.cache文件夹下,并改名为:
879741a7946b814455eee6c6ffde2984-ippicv_2020_win_intel64_20191018_general.zip


其他的包同上。不赘述。
这些拷贝结束之后,我们重新configure:

然后我们在看CmakeDownLoadLog.txt,已经不报错了:

cmake也不标红和报错了:

在cmake的OPENCV_EXTRA_MODULES_PATH之中输入之前下载的OpenCV-contrib的路径(精确到modules:


再次configure,然后又看到一大堆报错:

查看CmakeDownLoadLog.txt,是的,又来了:

再次下载吧。(有一说一,多了好多微信二维码的内容,不愧是你,腾讯!不愧是你,化腾!)
下载完成,再次configure,并查看CmakeDownLoadLog.txt,好的不报错了。PS:如果过程中发现CmakeDownLoadLog.txt还是有报错,继续下载,继续复制。
另外在多次configure过程中,每次都会尝试从.cache文件中获取原始文件,再拷贝到build之后的文件夹下面,复制的过程也会打日志的。建议多点几次configure。
最后我们查看CmakeDownLoadLog.txt,我们会看到如下信息:


终于都是match了,开心!
注:史前大坑:OPENCV_ENABLE_NONFREE一定要勾选上啊!否则Nonfree没法用。

上述工作检查无误,到了这一步才可以点击Generate哦。

找到build之后的OpenCV.sln文件,用VS打开。

右键项目,并点击“重新生成解决方案”:
另外这里只是生成了debug版本,后面记得把Release版本也生成一下,Debug和Relea版本都生成之后,后续的代码才能在debug和release两个环境下运行。

这一步会等很久,等待时间从2小时到12个小时不等。
(注:这里有点错误,参考了其他一些链接,实际上只需要对CMakeTargets文件夹下的Install进行重新生成即可,如下图,但是全部重新生成应该也不影响)。

之前安装OpenCV 3.X版本没有遇到过这个错误,这次遇到了,就尝试修复一下吧。参考链接4。
vs2022重新编译opencv-python cuda加速时报错_Harry Xu的博客-CSDN博客

解决方法的核心就是找到出错的文件,然后保存为Unicode格式的文件即可。
个人猜测这个问题不修复也不会怎么影响OpenCV大部分功能的使用。
然后重新生成,可以看到没有报错了(无论是debug还是release版本)。

注:如果只重新生成INSTALL的话,之前的报错应该是不会出现的。
只重新生成INSTALL之后,可以看到170个项目都成功了。

我们首先创建一个空的"控制台应用"项目,就叫OpenCVtest。
然后先配置系统环境变量,Windows控制台搜索即可查询到。

把之前install产出的bin的包的路径填进去。
然后重启电脑才会生效。


这里还是使用Release版本 x64的编译环境,debug的类似。
然后右键项目,更改属性:

然后编辑VC++目录下的包含目录(其实就是英文版本的include path):

然后把install之后的include文件夹路径添加上去(注意,是install之后的include路径,不要填错成了其他的include路径)

然后我们编辑库目录(其实就是英文版的lib path)

把install之后的lin目录输入进去(再次强调是install之后的lib目录)

链接器->附加依赖项->编辑,输入所有的xxxxx/install\x64\vc16\lib中 所有xxxd.lib文件名字:

这里建议使用windows命令行操作获取所有的XXX455.lib文件名(455是opencv版本名字,不同版本的opencv安装后,敲命令行使用不同的版本号哦)。
操作命令如下:
dir *.* /B | findstr 455.lib

复制进去:

然后我们开始测试。
为了验证我们安装OpenCV的效果,我们需要使用测试Case进行测试。
这里先测试OpenCV的基本功能,再使用SIFT算子和SURF算子进行测试。 由于SIFT算子和SURF算子都是OpenCV contrib里面才有的图像库,这两个算子能测试通过,说明OpenCV contrib安装完成(更正:opencv4.4之后sift又回到opencv普通库了……崩溃)。
在项目中输入下述代码:
// OpenCVTest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
cv::Mat src = cv::imread("E:\\images\\00000.jpg");//图片路径
if (src.empty())
{
std::cout << "pic is empty!\n";
return -1;
}
cv::imshow("show", src);
cv::waitKey(0);
std::cout << "Hello World!\n";
}
运行结果:

好了,说明能展示了。
参考上述文章:
代码如下:
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp> //OpenCV 4.2.0 及之后版本
int main()
{
cv::Mat imageL = cv::imread("E:\\images\\3.jpg");
cv::Mat imageR = cv::imread("E:\\images\\4.jpg");
//提取特征点方法
//SIFT
//cv::Ptr<cv::xfeatures2d::SIFT> sift = cv::xfeatures2d::SIFT::create();
cv::Ptr<cv::SIFT> sift = cv::SIFT::create(); //OpenCV 4.4.0 及之后版本
//ORB
//cv::Ptr<cv::ORB> orb = cv::ORB::create();
//SURF
//cv::Ptr<cv::xfeatures2d::SURF> surf = cv::xfeatures2d::SURF::create();
//特征点
std::vector<cv::KeyPoint> keyPointL, keyPointR;
//单独提取特征点
sift->detect(imageL, keyPointL);
sift->detect(imageR, keyPointR);
//画特征点
cv::Mat keyPointImageL;
cv::Mat keyPointImageR;
drawKeypoints(imageL, keyPointL, keyPointImageL, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
drawKeypoints(imageR, keyPointR, keyPointImageR, cv::Scalar::all(-1), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
//显示窗口
cv::namedWindow("KeyPoints of imageL");
cv::namedWindow("KeyPoints of imageR");
//显示特征点
cv::imshow("KeyPoints of imageL", keyPointImageL);
cv::imshow("KeyPoints of imageR", keyPointImageR);
//特征点匹配
cv::Mat despL, despR;
//提取特征点并计算特征描述子
sift->detectAndCompute(imageL, cv::Mat(), keyPointL, despL);
sift->detectAndCompute(imageR, cv::Mat(), keyPointR, despR);
//Struct for DMatch: query descriptor index, train descriptor index, train image index and distance between descriptors.
//int queryIdx –>是测试图像的特征点描述符(descriptor)的下标,同时也是描述符对应特征点(keypoint)的下标。
//int trainIdx –> 是样本图像的特征点描述符的下标,同样也是相应的特征点的下标。
//int imgIdx –>当样本是多张图像的话有用。
//float distance –>代表这一对匹配的特征点描述符(本质是向量)的欧氏距离,数值越小也就说明两个特征点越相像。
std::vector<cv::DMatch> matches;
//如果采用flannBased方法 那么 desp通过orb的到的类型不同需要先转换类型
if (despL.type() != CV_32F || despR.type() != CV_32F)
{
despL.convertTo(despL, CV_32F);
despR.convertTo(despR, CV_32F);
}
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased");
matcher->match(despL, despR, matches);
//计算特征点距离的最大值
double maxDist = 0;
for (int i = 0; i < despL.rows; i++)
{
double dist = matches[i].distance;
if (dist > maxDist)
maxDist = dist;
}
//挑选好的匹配点
std::vector< cv::DMatch > good_matches;
for (int i = 0; i < despL.rows; i++)
{
if (matches[i].distance < 0.5 * maxDist)
{
good_matches.push_back(matches[i]);
}
}
cv::Mat imageOutput;
cv::drawMatches(imageL, keyPointL, imageR, keyPointR, good_matches, imageOutput);
cv::namedWindow("picture of matching");
cv::imshow("picture of matching", imageOutput);
cv::waitKey(0);
return 0;
}
原始图像如下:


运行结果:

代码如下,参考了:
【OpenCV】OpenCV 4 下 SIFT、SURF的使用_魏Gordon的博客-CSDN博客_opencv4 surf
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/xfeatures2d/nonfree.hpp"
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/imgproc.hpp"
#include <opencv2/imgproc/types_c.h>
#include<opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;
int main()
{
//【0】改变console字体颜色
system("color 1F");
//【1】载入原始图片
Mat srcImage1 = imread("E:/images/3.jpg", 1);
Mat srcImage2 = imread("E:/images/4.jpg", 1);
Mat copysrcImage1 = srcImage1.clone();
Mat copysrcImage2 = srcImage2.clone();
if (!srcImage1.data || !srcImage2.data)
{
printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! \n"); return false;
}
//【2】使用SURF算子检测关键点
int minHessian = 100;//SURF算法中的hessian阈值
Ptr<SURF> detector = SURF::create(minHessian);//定义一个SurfFeatureDetector(SURF) 特征检测类对象
// Ptr<SURF> detector = cv::xfeatures2d::SURF::create(400);
vector<KeyPoint> keypoints_object, keypoints_scene;//vector模板类,存放任意类型的动态数组
//【3】调用detect函数检测出SURF特征关键点,保存在vector容器中
detector->detect(srcImage1, keypoints_object);
detector->detect(srcImage2, keypoints_scene);
//【4】计算描述符(特征向量)
Ptr<SURF> extractor = SURF::create();
Mat descriptors_object, descriptors_scene;
extractor->compute(srcImage1, keypoints_object, descriptors_object);
extractor->compute(srcImage2, keypoints_scene, descriptors_scene);
//【5】使用FLANN匹配算子进行匹配
FlannBasedMatcher matcher;
vector< DMatch > matches;
matcher.match(descriptors_object, descriptors_scene, matches);
double max_dist = 0; double min_dist = 100;//最小距离和最大距离
//【6】计算出关键点之间距离的最大值和最小值
for (int i = 0; i < descriptors_object.rows; i++)
{
double dist = matches[i].distance;
if (dist < min_dist) min_dist = dist;
if (dist > max_dist) max_dist = dist;
}
printf(">Max dist 最大距离 : %f \n", max_dist);
printf(">Min dist 最小距离 : %f \n", min_dist);
//【7】存下匹配距离小于3*min_dist的点对
std::vector< DMatch > good_matches;
for (int i = 0; i < descriptors_object.rows; i++)
{
if (matches[i].distance < 3 * min_dist)
{
good_matches.push_back(matches[i]);
}
}
//绘制出匹配到的关键点
Mat img_matches;
drawMatches(srcImage1, keypoints_object, srcImage2, keypoints_scene,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
//定义两个局部变量
vector<Point2f> obj;
vector<Point2f> scene;
//从匹配成功的匹配对中获取关键点
for (unsigned int i = 0; i < good_matches.size(); i++)
{
obj.push_back(keypoints_object[good_matches[i].queryIdx].pt);
scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt);
}
vector<unsigned char> listpoints;
//Mat H = findHomography( obj, scene, CV_RANSAC );//计算透视变换
Mat H = findHomography(obj, scene, RANSAC, 3, listpoints);//计算透视变换
std::vector< DMatch > goodgood_matches;
for (int i = 0; i < listpoints.size(); i++)
{
if ((int)listpoints[i])
{
goodgood_matches.push_back(good_matches[i]);
cout << (int)listpoints[i] << endl;
}
}
cout << "listpoints大小:" << listpoints.size() << endl;
cout << "goodgood_matches大小:" << goodgood_matches.size() << endl;
cout << "good_matches大小:" << good_matches.size() << endl;
Mat Homgimg_matches;
drawMatches(copysrcImage1, keypoints_object, copysrcImage2, keypoints_scene,
goodgood_matches, Homgimg_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
imshow("去除误匹配点后;", Homgimg_matches);
//从待测图片中获取角点
vector<Point2f> obj_corners(4);
obj_corners[0] = cvPoint(0, 0); obj_corners[1] = cvPoint(srcImage1.cols, 0);
obj_corners[2] = cvPoint(srcImage1.cols, srcImage1.rows); obj_corners[3] = cvPoint(0, srcImage1.rows);
vector<Point2f> scene_corners(4);
//进行透视变换
perspectiveTransform(obj_corners, scene_corners, H);
//绘制出角点之间的直线
line(img_matches, scene_corners[0] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[1] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 4);
line(img_matches, scene_corners[1] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[2] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 4);
line(img_matches, scene_corners[2] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[3] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 4);
line(img_matches, scene_corners[3] + Point2f(static_cast<float>(srcImage1.cols), 0), scene_corners[0] + Point2f(static_cast<float>(srcImage1.cols), 0), Scalar(255, 0, 123), 4);
//显示最终结果
imshow("效果图", img_matches);
waitKey(0);
return 0;
}
测试结果如下。

在OpenCV4.X版本中,SURF依然是OpenCV contrib中的代码。SURF代码测试成功,说明我们的安装已经成功了。
看到这里的都不容易,大家休息一下吧,下一步就可以考虑修改源码啦。
OpenCV的安装的确是一个非常复杂和麻烦的过程,即使我之前已经有了成功安装的经验,这一次安装(加写教程)还是花了我大约一天的时间。
在安装过程中,主要注意以下几点:
1.cmake阶段注意查看Cmake的报错信息,及时检查CMakeDownLog.txt文件;
2.根据日志文件自行下载相应的依赖;
3.最后的测试case能够跑通才算完成整个安装流程。
VS2019+OpenCV4.1.0安装及整合详细步骤 - 简书
OpenCV3.3+contrib+VS2017+CMake+Win10_码代马的博客-CSDN博客
OpenCV+opencv_contrib+VS2015+CMake+Win10编译过程_TechGreat的博客-CSDN博客_cmake opencv_contrib
vs2022重新编译opencv-python cuda加速时报错_Harry Xu的博客-CSDN博客win10 +visual studio 2019 +opencv4.5.0+opencv_contrib4.5.0源码编译安装_语符律的博客-CSDN博客_win10安装opencv4.5
OpenCV3.4.0+Visual Studio2017配置 - 上中下,高平宽 - 博客园
opencv::sift特征提取 - osbreak - 博客园
【VS2017】【OpenCV4.0.0】调用SIFT出错_啊吼!的博客-CSDN博客
安装OpenCV已经这么费劲了,不如继续改改源码?
关于如何修改OpenCV的源码(以修改SURF算子为例),请参考下一篇文章:
OpenCV 修改源码:基于hpp文件,修改SURF算子(支持打断点、调试、debug)_树叶的叶and开心的开的博客-CSDN博客
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我打算为ruby脚本创建一个安装程序,但我希望能够确保机器安装了RVM。有没有一种方法可以完全离线安装RVM并且不引人注目(通过不引人注目,就像创建一个可以做所有事情的脚本而不是要求用户向他们的bash_profile或bashrc添加一些东西)我不是要脚本本身,只是一个关于如何走这条路的快速指针(如果可能的话)。我们还研究了这个很有帮助的问题:RVM-isthereawayforsimpleofflineinstall?但有点误导,因为答案只向我们展示了如何离线在RVM中安装ruby。我们需要能够离线安装RVM本身,并查看脚本https://raw.github.com/wayn
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
我刚刚为fedora安装了emacs。我想用emacs编写ruby。为ruby提供代码提示、代码完成类型功能所需的工具、扩展是什么? 最佳答案 ruby-mode已经包含在Emacs23之后的版本中。不过,它也可以通过ELPA获得。您可能感兴趣的其他一些事情是集成RVM、feature-mode(Cucumber)、rspec-mode、ruby-electric、inf-ruby、rinari(用于Rails)等。这是我当前用于Ruby开发的Emacs配置:https://github.com/citizen428/emacs
我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121
由于fast-stemmer的问题,我很难安装我想要的任何rubygem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub