opencv用法

读写xml文件

opencv

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*)&num;
 
    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:

 

 

 

 

 

 

 

 

 
 
 

 

posted @ 2021-04-08 21:01  小小灰迪  阅读(234)  评论(0编辑  收藏  举报