opencv用法
读写xml文件
fs1 = cv2.FileStorage("./Date/gpsPoints.xml", cv2.FILE_STORAGE_READ) endGps_Node = fs1.getNode("gpsMiddle") endGps_lat = endGps_Node.getNode("latitude").real() endGps_lon = endGps_Node.getNode("longitude").real() endGps_alt = endGps_Node.getNode("altitude").real() gps1 = fs1.getNode("Gps1").mat() print(gps1, gps1[0][0]) fs1.release() fs2 = cv2.FileStorage("./Date/gpsRecordOnline.xml", cv2.FILE_STORAGE_WRITE) fs2.write("gps"+str(times).zfill(4), gpsMartix) fs2.release() cv2.FILE_STORAGE_APPEND
cv::Mat ret_R_mat; cv::Mat ret_t_mat; cv::eigen2cv(ret_R_srt, ret_R_mat); cv::eigen2cv(ret_t_srt, ret_t_mat); cv::FileStorage fs; fs.open("srt.xml", cv::FileStorage::WRITE); std::cout << "s:" << s_srt << std::endl; std::cout << "ret_r:" << ret_R_mat << std::endl; std::cout << "ret_t" << ret_t_mat << std::endl; fs<<"ret_r"<<ret_R_mat; fs<<"ret_t"<<ret_t_mat; fs<<"s"<<s; fs.release();
python opencv 矩阵拼接
img=cv2.hconcat([img,img,img])#水平拼接 img=cv2.vconcat([img,img,img])#垂直拼接 h_ = np.array([[0,0,0,1]]) RT_44 = np.r_[RT_34, h_] # 增加一行 b_ = np.array([[0,0,1]]) RT_35 = np.r_[RT_34, b_.T] # 增加一列
imread()
使用函数cv2.imread(filepath,flags)读入一副图片
filepath:要读入图片的完整路径
flags:读入图片的标志
cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道,可以直接写1
cv2.IMREAD_GRAYSCALE:读入灰度图片,可以直接写0
cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道,可以直接写-1
opencv窗口
img = cv2.imread(in_filename) cv2.namedWindow('test', cv2.WINDOW_NORMAL) cv2.resizeWindow('test',1000, 1000) cv2.imshow('test',img) cv2.waitKey(0) cv2.destoryAllWindows()
img = cv2.imread('0000.png')
img_copy = img.copy()
print(img_copy.shape)
img_width = img_copy.shape[1]
img_height = img_copy.shape[0]
cv::Mat descriptors_;
rows:Mat矩阵的行数。
cols: Mat矩阵的列数。
size():image.size().width==image.cols; image.size().height==image.rows
std::cout<<"descriptors_size: "<< descriptors_.size()<<" rows: "<< descriptors_.rows<< " cols: "<< descriptors_.cols<<std::endl;
常用形式:
mat.ptr<type>(row)[col]
对于Mat的ptr函数,返回的是<>中的模板类型指针,指向的是()中的第row行的起点
通常<>中的类型和Mat的元素类型应该一致
然后再用该指针去访问对应col列位置的元素
for (unsigned int i = 0; i < keypts.size(); ++i) { compute_orb_descriptor(keypts.at(i), image, descriptors.ptr(i)); }
u_char desc = descriptors_.ptr<u_char>(1)[0];
输出uchar二进制值
void printf_bin_8(unsigned char num) { int k; unsigned char *p = (unsigned char*)# for (int k = 7; k >= 0; k--) //处理8个位 { if (*p & (1 << k)) printf("1"); else printf("0"); } printf("\n"); }
imread()
cv::Mat img = cv::imread("/data/limg_pts.pgm", cv::IMREAD_COLOR); //cv::IMREAD_COLOR // if set, always convert image to the 3 channel BGR color image.
cv::cvtColor()
【OpenCV3】颜色空间转换——cv::cvtColor()详解
去读图片以CV_32FC1读取
cv::imread("/home/lhw/Gradute/openvslam/openvslam-cudasift/CudaSift/data/img1.png", 0).convertTo(limg, CV_32FC1);
获取Mat矩阵的最大值、最小值及位置
double minValue, maxValue; // 最大值,最小值 cv::Point minIdx, maxIdx; // 最小值坐标,最大值坐标 cv::minMaxLoc(limg, &minValue, &maxValue, &minIdx, &maxIdx); std::cout << "最大值:" << maxValue <<"最小值:"<<minValue<<std::endl; std::cout << "最大值位置:" << maxIdx << "最小值位置:" << minIdx;
将CV_32FC1转化为CV_8UC1,参考
cv::Mat des1; double minValue, maxValue; // 最大值,最小值 cv::Point minIdx, maxIdx; // 最小值坐标,最大值坐标 cv::minMaxLoc(limg, &minValue, &maxValue, &minIdx, &maxIdx); std::cout << "最大值:" << maxValue <<"最小值:"<<minValue<<std::endl; std::cout << "最大值位置:" << maxIdx << "最小值位置:" << minIdx; if(minValue!=maxValue){ limg.convertTo(des1,CV_8UC1, 255.0/(maxValue-minValue),-255.0*minValue/(maxValue-minValue)); cv::imshow("limg-1", des1); cv::waitKey(0); }
cv::Dmatch
struct CV_EXPORTS DMatch { DMatch() : queryIdx(-1), trainIdx(-1), imgIdx(-1), distance(std::numeric_limits<float>::max()) {} DMatch( int _queryIdx, int _trainIdx, float _distance ) : queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1), distance(_distance) {} DMatch( int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) : queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx), distance(_distance) {} int queryIdx; // query descriptor index int trainIdx; // train descriptor index int imgIdx; // train image index ss float distance; // less is better bool operator<( const DMatch &m ) const { return distance < m.distance; } };
matcher->match(desc_1, desc_2, matches); // 查询特征点的下标,也就是desc_1的特征点的下标 matches[i].queryIdx // 匹配特征点的下标,也就是desc_2的特征点的下标 matches[i].trainIdx //两个描述子的欧氏距离 matches[i].distance //匹配图像索引,适用于多张图像的匹配 matches[i].imgIdx // matches的大小为desc_1的大小,如果desc_1与desc_2调换位置那么matches的大小为desc_2的大小
对Dmath进行遍历:
i: 1437 queryIdx: 1437 trainIdx: 1453 i: 1438 queryIdx: 1438 trainIdx: 1449 i: 1439 queryIdx: 1439 trainIdx: 1613 i: 1440 queryIdx: 1440 trainIdx: 1427 i: 1441 queryIdx: 1441 trainIdx: 1468 i: 1442 queryIdx: 1442 trainIdx: 1443 i: 1443 queryIdx: 1443 trainIdx: 1471 i: 1444 queryIdx: 1444 trainIdx: 1461 i: 1445 queryIdx: 1445 trainIdx: 1476 i: 1446 queryIdx: 1446 trainIdx: 1465 i: 1447 queryIdx: 1447 trainIdx: 1464 i: 1448 queryIdx: 1448 trainIdx: 1387 i: 1449 queryIdx: 1449 trainIdx: 907 i: 1450 queryIdx: 1450 trainIdx: 1469 i: 1451 queryIdx: 1451 trainIdx: 1470 i: 1452 queryIdx: 1452 trainIdx: 1405 i: 1453 queryIdx: 1453 trainIdx: 1469
如第一行: i: 1437 queryIdx: 1437 trainIdx: 1453 是 cv::Dmatch matches[1437] 的数据
queryIdx就是decs_1的下标,trainIdx就是在decs_1的第1437+1的描述子匹配到desc_2的描述子在desc_2的下标
decs_1的每个描述子都会对应一个desc_2的描述子,也会出现一对多的情况
这样得到的匹配点肯定是粗匹配,后面需要对匹配的特征点进行筛选
1.利用欧式距离进行筛选,高于某一阈值的匹配点舍弃(欧式距离越小越好)
2.基础矩阵筛选
3.单应矩阵筛选
画十字架
def drawCross(self, img, point, color, thickness=1, lineType=cv2.LINE_8, shift=0): cv2.line(img, (point[0] - 5, point[1]), (point[0] + 5, point[1]), (color[0], color[1], color[2]), thickness, lineType, shift) cv2.line(img, (point[0], point[1]-5), (point[0], point[1]+5), (color[0], color[1], color[2]), thickness, lineType, shift) return
findcontour
void findcontour(const Mat &mask, const double &thr, vector<vector<Point>> &contours_list) { Mat gray, binary, mask_copy; vector<vector<Point>> contours; vector<Vec4i> hierarchy; mask_copy = mask.clone(); cvtColor(mask_copy, gray, COLOR_BGR2GRAY); threshold(gray, binary, 200, 255, THRESH_BINARY); findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE); double area = 0; for (int idx = 0; idx < contours.size(); idx++) { area = contourArea(contours[idx]); if (area > thr) { contours_list.push_back(contours[idx]); } } }
外接正矩形和最小外接矩形
boundingRect()、minAreaRect()
输入为contours的contour
output: