标签:
uchar blue = intensity.val[0];
uchar green = intensity.val[1];
uchar red = intensity.val[2];
?
float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];
?
//... fill the array
Mat pointsMat = Mat(points);
?
想取得这个矩阵里的点可以使用Mat:: at:
?
Point2f point = pointsMat.at<Point2f>(i, 0);
?
// .. fill the array
Mat pointsMat = Mat(points).reshape(1);
执行上面的语句,我们就可以将一列的32FC3矩阵转换成三列的32FC3矩阵。pointsMat使用的数据就是points的数据,也就是说当清除pointsMat时,数据并没有被清除。在这个例子中,使用者需要确保points的生命周期比pointsMat长。如果我们要复制数据,可以使用Mat::copyTo or Mat::clone:
Mat img = imread("image.jpg");
Mat img1 = img.clone();
?
Mat img = imread("image.jpg");
Mat sobelx;
Sobel(img, sobelx, CV_32F, 1, 0);
?
注:reference count(引用计数):每个对象都有一个引用计数用来表明有多少其它对象正在保留一个对它的引用,对象A想要引用对象B,A就把B的引用计数加一,当A结束了对B的引用,A就把B的引用计数减一,当没有对象再引用B时,B的引用计数就为0,B就被清除(deallocate)。
?
有一些定义在矩阵层面上的操作。
img = Scalar(0);
? ?
Selecting a region of interest:
Rect r(10, 10, 100, 100);
Mat smallImg = img(r);
? ?
? ?
Mat img = imread("image.jpg");
IplImage img1 = img;
CvMat m = img;
? ?
注意:上面的语句并没有复制数据。
? ?
? ?
Mat img = imread("image.jpg"); // loading a 8UC3 image
Mat grey;
cvtColor(img, grey, CV_BGR2GRAY);
? ?
把图像类型从8UC1 (8比特无符号单通道类型)转换到32FC1(32比特浮点单通道类型):
? ?
src.convertTo(dst, CV_32F);
在开发过程中,显示你的算法的中间结果也是很实用的技巧。OpenCV提供了一个很方便的方法。一个8U类型的图像显示方法:
?
Mat img = imread("image.jpg");
namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", img);
waitKey();
? ?
调用waitKey()程序会等待用户的键盘输入(在image窗口)。32F类型型的图像显示要转换成8U类型的。下面是一个例子:
?
Mat img = imread("image.jpg");
Mat grey;
cvtColor(img, grey, CV_BGR2GRAY);
Mat sobelx;
Sobel(grey, sobelx, CV_32F, 1, 0);
double minVal, maxVal;
minMaxLoc(sobelx, &minVal, &maxVal); //find minimum and maximum intensities
Mat draw;
sobelx.convertTo(draw, CV_8U, 255.0/(maxVal - minVal), -minVal * 255.0/(maxVal - minVal));
namedWindow("image", CV_WINDOW_AUTOSIZE);
imshow("image", draw);
waitKey();
? ?
Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
if(img1.empty() || img2.empty())
{
printf("Can‘t read one of the images\n");
return -1;
}
?
// detecting keypoints
SurfFeatureDetector detector(400);
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
?
// computing descriptors
SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
?
// matching descriptors
BruteForceMatcher<L2<float> > matcher;
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
?
// drawing the results
namedWindow("matches", 1);
Mat img_matches;
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
imshow("matches", img_matches);
waitKey(0);
? ?
Mat img1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
Mat img2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
if(img1.empty() || img2.empty())
{
printf("Can‘t read one of the images\n");
return -1;
}
载入两幅图像,并且检查是否成功载入。
?
// detecting keypoints
FastFeatureDetector detector(15);
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);
首先创建一个特征点检测的对象。对象继承了FeatureDetector类的抽象接口,但结构还是取决于算法。detector对象的第一个参数用于平衡检测到的特征点的数量和质量(稳定性)。不同的检测方法这个参数的取值也不同(例如:FAST算子的阈值有像素强度差值的意义,取值通常在0~40。SURF算子的阈值应用在卷积图像的Hessian矩阵上,取值通常大于100),这里我们取的默认值。
?
// computing descriptors
SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);
? ?
创建一个描述符提取(descriptor extractor)对象。OpenCV中大多数描述符(descriptors)继承了DescriptorExtractor的抽象接口。然后为每一个特征点计算描述符(descriptors)。DescriptorExtractor::compute方法输出为Mat,每一行是一个特征点的描述符,第i行描述符对应一第i个特征点。这里要注意的是这个方法会修改
存储keypoints的vector对象(keypoints vector),他会删除一些特征点,自然这些特征点的描述符就不会被创建(通常被删除的点都是图像边缘的点)。这样就可以确保输出的特征点和描述符一一对应(特征点的数量和秘书符的数量是相等的)。
?
// matching descriptors
BruteForceMatcher<L2<float> > matcher;
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);
现在我们有了两幅图像的描述符,就可以对他们执行匹配。先创建一个matcher对象,对image 2的每个描述子用欧几里德向量穷举搜索image 1中与它最近的描述子。
曼哈坦距离(Manhattan distance)和汉明距离(Hamming distance)同时使用以获得简要结果。输出的matches包含一对对的索引,每对索引就是匹配好的描述符。
?
// drawing the results
namedWindow("matches", 1);
Mat img_matches;
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
imshow("matches", img_matches);
waitKey(0);
最后的部分就是将处理结果显示出来。
标签:
原文地址:http://www.cnblogs.com/programnote/p/4682882.html