现在的位置: 首页 > 综合 > 正文

openCV,一些问题

2017年12月21日 ⁄ 综合 ⁄ 共 4380字 ⁄ 字号 评论关闭
openCV,C++接口,PCA:

   PCA是高维数据线性降维的一个常用算法,在openCV的较早版本里面,已经有C版本的集成。在openCV更新的版本发布后,其中集成的PCA算法也有了C++接口。
    PCAC++接口的使用,可以参见链接
视频读取、写入解码器:
    openCV 2.3.1 中有一个宏CV_FOURCC,给定适当的参数,就设置对应的视频解码器,有如下一些选择:
CV_FOURCC('P', 'I', 'M', '1') = MPEG-1codec
CV_FOURCC('M', 'J', 'P', 'G') =motion-jpeg codec (does not work well)
CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2codec
CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3codec
CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4codec
CV_FOURCC('U', '2', '6', '3') = H263codec
CV_FOURCC('I', '2', '6', '3') = H263Icodec
CV_FOURCC('F', 'L', 'V', '1') = FLV1codec
   目前个人感觉 CV_FOURCC('D', 'I', 'V', '3')比较好用,其它有的解码器用openCV写的视频在有的地方就莫名其妙的打不开(尤其是 CV_FOURCC('M','J', 'P', 'G') )。

cv::VideoCapture的属性:
   使用该类的get函数可以获取视频流的属性,具体属性有这些:
'PosMsec'      Current position of the video file inmilliseconds or video capture timestamp.
'PosFrames'     0-basedindex of the frame to be decoded/captured next.
'AVIRatio'     Relative position of the video file: 0 - start ofthe film, 1 - end of the film.
'FrameWidth'    Width of theframes in the video stream.
'FrameHeight'   Height of the frames in thevideo stream.
'FPS'          Frame rate.
'FourCC'       4-character code ofcodec.
'FrameCount'    Number offrames in the video file.
'Format'       Format of the Mat objectsreturned by retrieve() .
'Mode'        Backend-specific value indicating the currentcapture mode.
'Brightness'    Brightnessof the image (only for cameras).
'Contrast'     Contrast of the image (only for cameras).
'Saturation'    Saturationof the image (only for cameras).
'Hue'          Hue of the image (only forcameras).
'Gain'         Gain of theimage (only for cameras).
'Exposure'     Exposure (only for cameras).
'ConvertRGB'    Booleanflags indicating whether images should be converted to RGB.
'Rectification' Rectification flag for stereo cameras (note:only supported by DC1394 v 2.x backend currently)
    上述属性在get()中都应该写成CV_CAP_PROP_POS_AVI_RATIO 的枚举类型的形式。
C++ 接口中的图像特征检测:
   常用的图像特征有SIFT、SUFR、Harris等,在OpenCV的C++接口中基本都完成了类封装。
    使用openCVC++接口的SIFT特征的一个例子如下:
Mat img_1 = imread( "frame1.tiff",CV_LOAD_IMAGE_GRAYSCALE );
Mat img_2 = imread( "frame2.tiff",CV_LOAD_IMAGE_GRAYSCALE );

if( !img_1.data || !img_2.data)
{std::cout<< " --(!) Error readingimages " << std::endl; return -1;}

SiftFeatureDetectordetector;

std::vector<KeyPoint>keypoints_1, keypoints_2;

detector.detect( img_1, keypoints_1);
detector.detect( img_2, keypoints_2);

Mat img_keypoints_1; Matimg_keypoints_2;

drawKeypoints( img_1, keypoints_1,img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
drawKeypoints( img_2, keypoints_2,img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT);

imshow("Keypoints 1", img_keypoints_1);
imshow("Keypoints 2", img_keypoints_2);

waitKey(0);
   其实openCV中有一个 FeatureDetector基类,从中派生出了很多诸如 SiftFeatureDetector、SurfFeatureDetector的特征类。其使用方法都与上述例子大同小异。
   除了提取特征点之外,关于特征点描述子(descriptor)的提取,以及不同图像的特征匹配,openCV也都有封装,具体见下面SIFT的例子:
Mat img_1 = imread( "frame1.tiff",CV_LOAD_IMAGE_GRAYSCALE );
Mat img_2 = imread( "frame2.tiff",CV_LOAD_IMAGE_GRAYSCALE );

if( !img_1.data || !img_2.data)
{ return -1; }

SiftFeatureDetectordetector;

std::vector<KeyPoint>keypoints_1, keypoints_2;

detector.detect( img_1, keypoints_1);
detector.detect( img_2, keypoints_2);

SiftDescriptorExtractorextractor;

Mat descriptors_1,descriptors_2;

extractor.compute( img_1, keypoints_1,descriptors_1 );
extractor.compute( img_2, keypoints_2,descriptors_2 );

BruteForceMatcher<L2<float> >matcher;
std::vector< DMatch> matches;
matcher.match( descriptors_1,descriptors_2, matches );

Mat img_matches;
drawMatches( img_1, keypoints_1, img_2,keypoints_2, matches, img_matches );

imshow("Matches", img_matches);
waitKey(0);

cv::Mat 重新定义大小,cv::resize:
一个例子是,
cv::resize( tmpImgIn, tmpImgOut, cv::Size(_width,_height));
openCV解一元三次方程:
cv::solveCubic(const Mat& coeffs,Mat& roots);
openCV解高次方程(多项式方程):
cv::solvePoly
openCV解线性方程组 or 用最小二乘法解线性方程组:
cv::solve(coeff, roots)
注意如果结果是复数,则结果 roots 是多通道的(虚数通道是通道2),一般类型为CV_32FC2
openCV已经封装了输出运算符“<<”对 cv::Mat的重载,可以直接用cout看结果
一个例子见:
注意coeff中是按从低次(0次)到高次的顺序来存放系数的。
cv::Mat coeff;
cv::Mat roots;
coeff.create(3, 1,CV_32FC1);
coeff.at<float>(0,0) =4.0;
coeff.at<float>(1,0) =0.0;
coeff.at<float>(2,0) =1.0;
cv::solvePoly(coeff,roots);
printf("%d\n",roots.channels());
cout<<roots<<endl;
将 cv::Mat 的所有元素设为一个值:
直接用赋值号即可,例如
cv::Mat m(100, 100, CV_8UC1);//gray 
m = cv::Scalar(5); //used onlyScalar.val[0] 

cv::Mat m(100, 100, CV_8UC3);//3-channel 
m = cv::Scalar(5, 10, 15); //Scalar.val[0-3]used 

使用 at 函数读取 cv::Mat 的多通道数据:
一个例子为:
cv::Mat roots;
roots.create(2,2,CV_32FC2);
for(int i=0; i<2; i++) {
    for(int j=0;j<2; j++) {
       printf("%f %f\n",roots.at<float>(i,j*2+0),   // 通道0(i,j)
                     roots.at<float>(i,j*2+1));  // 通道1(i,j)
    }
}

矩阵乘法常用函数:
cv::gemm

cv::Size
cv::Size tsize(100,200);
cout<<tsize.width<<""<<tsize.height<<endl;
输出结果是“100 200”,即先width、后height

抱歉!评论已关闭.