OpenCV中数组指针、图像分块计算、指针取像素值与MatToEigen方法—— OpenCV (零)



  {
Topic1:
高效开辟内存,使适用于大型数组。

//开辟新数组,或者开辟新的0或者某一数值的数组/Mat或者Map直接使用memset
//大数组操作效率较高
举例1:
	  cv::Mat cv_ncc_temp(cv_input_32f.rows, cv_input_32f.cols, CV_8UC1);
	  memset(cv_ncc_temp.data, 0, cv_input_32f.rows*cv_input_32f.cols * sizeof(uint8_t));
举例2:
	  memset(cv_binary_image.data, 255, cv_input_32f.rows*cv_input_32f.cols / 4);
举例3:
	  cv::Mat block_flag(max_row, max_col, CV_8UC1);
	  memset(block_flag.data, 0, max_row * max_col * sizeof(uint8_t));


//行指针如下
举例1:*****注意 行指针,整行取出所有元素,列变量便利有两种方式第一种通过pncc++,指针的方式来操控元素沿着列方向遍历。
	  for (int i = xy_off; i < cv_input_32f.rows - xy_off; ++i) {
		  uint8_t* psen = cv_ncc_result_temp.ptr<uint8_t>(i);
		  float* pncc = cv_ncc_result.ptr<float>(i - xy_off);
		  for (int j = xy_off; j < cv_input_32f.cols - xy_off; ++j) {
			  *psen = (uint8_t)((*(pncc-xy_off) + 1)*127.5f);
			  pncc++;
			  psen++;
		  }
	  }
等价于:
cv_ncc_result.at<uint8_t>(i,j) = (uint8_t)((cv_ncc_result_temp.at<float>(i-xy_off,j-xy_off))+1)*127.5f

举例2:*****行指针去除整行,列指针通过 *(psen+j)随着for循环中的j增加而移动,与举例1中常用的两种方式。
    内存溢出情况:主要差一些指针上线,尤其是上限边缘出,当不规则的分块或者分类出现时,内存溢出常出现的位置位于此的概率增大。
	  for (int row = 0; row < max_row - 1; ++row) {
		  uint8_t* pblock = block_flag.ptr<uint8_t>(row);
		  for (int col = 0; col < max_col - 1; ++col) {
			  int count = 0;
			  for (int i = row * BLOCK_HEIGHT; i < (row + 1) * BLOCK_HEIGHT; i++) {
				  uint8_t* psen = cv_ncc_result_temp.ptr<uint8_t>(i);
				  for (int j = col * BLOCK_WIDTH; j < (col + 1) * BLOCK_WIDTH; j++) {
					  if ((*(psen + j)) > 165 && (*(psen + j)) < 179) {
						  count++;
					  }
				  }
			  }
			  if (count > 60) {
				  *(pblock + col) = 1;
			  }
		  }
	  }
Topic2:
多指针同时操作,图像分块赋值,指针越界问题定位思路
举例3:*****1)不同for循环中的不同名称的指针不会相互影响
            2)*(pblock1 + (j >> 6)等价于
                block_flag.at<uint8_t>(i/64,j/64) == 0

	  for (int i = 0; i < cv_input_32f.rows; ++i) {
		  uint8_t* pdata = cv_ncc_result_temp.ptr<uint8_t>(i);
		  uint8_t* pblock1 = block_flag.ptr<uint8_t>(i >> 6);///
		  for (int j = 0; j < cv_input_32f.cols; ++j) {
			  if (*(pblock1 + (j >> 6)) == 0)///
			  {
				  if (*(pdata + j) < BACK_GROUND) {
					  (*(pdata + j)) = 0;
				  }
			  }
			  else {
				  if (*(pdata + j) < FORE_GROUND) {
					  (*(pdata + j)) = 0;
				  }
			  }
		  }
	  }


Topic3:
Eigen::Map与Mat相互转换
举例1:通过指针操作将cv_ncc_result_temp的值赋值给blurred_image,完成Mat到eigen::map的转换
	  for (int i = xy_off; i < cv_input_32f.rows - xy_off; ++i) {
		  uint8_t* pdata = cv_ncc_result_temp.ptr<uint8_t>(i);
		  for (int j = xy_off; j < cv_input_32f.cols - xy_off; ++j) {
			  uint8_t* pimage = (uint8_t*)(&blurred_image((i + roi[1]), (j + roi[0])));//取指针,以指针元素操作,提高操作效率
			  *pimage = (uint8_t) *(pdata + j);
		  }
	  }
举例2:通过指针操作完成cv_binary_image到binary_image的赋值,完成Mat到eigen::map的转换
	  for (int i = 0; i < (int)(roi_rect.height / scale_binary); ++i) {
		  uint8_t* pimage1 = (uint8_t*)(&binary_image(i + roi[1] / scale_binary, roi[0] / scale_binary));
		  memcpy(pimage1, cv_binary_image.ptr<uint8_t>(i), roi_rect.width / scale_binary);
	  }
  }

注意:

Eigen头文件要在opencv的eigen.hpp之前,否则报错!

Eigen中Matrix 与OpenCV中Mat间的转换

matrix->mat:eigen2cv

vector->mat:eigen2cv

mat->matrix:cv2eigen

mat->vector:cv2eigen 

  Matx33d EE;
  for (int i = 0; i<3; i++)
	  for (int j = 0; j < 3; j++) {
		  //std::cout << "E =" << E.at<double>(i, j) << std::endl;
		  EE(i, j) = E.at<double>(i, j);
		  //std::cout << "E =" << EE(i, j) << std::endl;
	  }

  std::cout << "EE =" << EE << std::endl;

Eigen与Opencv之间的转换,在包含Eigen库的基础上,#include<opencv2/core/eigen.hpp>

rr = (cv::Mat_<double>(3, 3) << -0.0001, -0.2, 3, 4, 5, 6, 7, 8, 791);

将Eigen::Matrix转换为cv::Mat

cv::eigen2cv(matrix,mat);

  Matx33d EE;
  for (int i = 0; i<3; i++)
	  for (int j = 0; j < 3; j++) {
		  //std::cout << "E =" << E.at<double>(i, j) << std::endl;
		  EE(i, j) = E.at<double>(i, j);
		  std::cout << "E =" << EE(i, j) << std::endl;
	  }

  std::cout << "EE =" << EE << std::endl;  

std::string filename3 = "./debug_output/xEx_output.txt";
  FILE* fp3 = fopen(filename3.c_str(), "at+");

  for (int i = 0; i < points1.size(); i++) {

	  Vec3d x1(points1[i].x, points1[i].y, 1.);
	  Vec3d x2(points2[i].x, points2[i].y, 1.);
	 // Matx33d E(model.ptr<double>());
	 // E = cv::eigen2cv(E, ee);
	 // Eigen::Matrix3d er;
	  //cv::cv2eigen(E, er);
	  cv::Mat rr;
	  Eigen::Matrix3d er;
	  
	 // rr = (cv::Mat_<double>(3, 3) << -0.0001, -0.2, 3, 4, 5, 6, 7, 8, 791);
	 // cv::cv2eigen(rr, er);  //cv  to eigen 
	  Matx33d EE(-0.0001, -0.2, 3, 4, 5, 6, 7, 8, 791);
	  Vec3d Ex1 = EE * x1;
	  Vec3d Etx2 = EE.t() * x2;
	  float x2tEx1 = x2.dot(Ex1);

	   fprintf(fp3,
	           "%10.8f\n",
		       x2tEx1);
	   } 

  fclose(fp3);

A::BB(目标类型)cConverter::XXXX(const C::DD(代转类型) &XXX){……} 

cv::Mat cConverter::toCvMatInverse(const cv::Mat &Tcw)
    {
        cv::Mat Rcw = Tcw.rowRange(0,3).colRange(0,3);
        cv::Mat tcw = Tcw.rowRange(0,3).col(3);
        cv::Mat Rwc = Rcw.t();
        cv::Mat twc = -Rwc*tcw;

        cv::Mat Twc = cv::Mat::eye(4,4,Tcw.type());
        Rwc.copyTo(Twc.rowRange(0,3).colRange(0,3));
        twc.copyTo(Twc.rowRange(0,3).col(3));

        return Twc.clone();
    }

        cv::Mat cConverter::toCvMat(const Eigen::Matrix<double,3,1> &m)
    {
          cv::Mat cvMat(3,1,CV_32F);
          for(int i=0;i<3;i++)
            cvMat.at<float>(i)=m(i);
          return cvMat.clone();
    }

        cv::Mat cConverter::Matrix3dtoCvMat(const Eigen::Matrix3d &m)
    {
        cv::Mat cvMat(3,3,CV_32F);
        for(int i=0;i<3;i++)
        for(int j=0; j<3; j++)
        cvMat.at<float>(i,j)=m(i,j);

        return cvMat.clone();
    }

    cv::Mat cConverter::Matx33dtoCvMat(const Eigen::Matrix3d &m)
    {
        cv::Mat cvMat(3,3,CV_32F);
        for(int i=0;i<3;i++)
        for(int j=0; j<3; j++)
            cvMat.at<float>(i,j)=m(i,j);

        return cvMat.clone();
    }

        cv::Mat cConverter::Matx44dtoCvMat(const Eigen::Matrix<double,4,4> &m)
    {
        cv::Mat cvMat(4,4,CV_32F);
        for(int i=0;i<4;i++)
        for(int j=0; j<4; j++)
            cvMat.at<float>(i,j)=m(i,j);

        return cvMat.clone();
    }

        Eigen::Matrix<double,3,1> cConverter::toVector3d(const cv::Mat &cvVector)
    {
        Eigen::Matrix<double,3,1> v;
        v << cvVector.at<float>(0), cvVector.at<float>(1), cvVector.at<float>(2);

        return v;
      }

      Eigen::Matrix<double,3,3> cConverter::toMatrix3d(const cv::Mat &cvMat3)
      {
          Eigen::Matrix<double,3,3> M;

          M << cvMat3.at<float>(0,0), cvMat3.at<float>(0,1), cvMat3.at<float>(0,2),
          cvMat3.at<float>(1,0), cvMat3.at<float>(1,1), cvMat3.at<float>(1,2),
          cvMat3.at<float>(2,0), cvMat3.at<float>(2,1), cvMat3.at<float>(2,2);

          return M;
      }
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    cv::Matx44d cConverter::invMat(const cv::Matx44d& M)
    {
        cv::Matx33d R = M.get_minor<3, 3>(0, 0);
        R = R.t();
        cv::Vec3d t(M(0, 3), M(1, 3), M(2, 3));
        t = -R * t;
        cv::Matx44d out(
            R(0, 0), R(0, 1), R(0, 2), t(0),
            R(1, 0), R(1, 1), R(1, 2), t(1),
            R(2, 0), R(2, 1), R(2, 2), t(2),
            0.0, 0.0, 0.0, 1.0);

        return out;
    }

    cv::Matx<double, 4, 4> cConverter::ogv2ocv(const Eigen::Matrix<double, 3, 4>& ogv_mat)
    {
        cv::Matx34d ocv_mat;
        cv::eigen2cv(ogv_mat, ocv_mat);

        return cv::Matx<double, 4, 4>(
            ocv_mat(0, 0), ocv_mat(0, 1), ocv_mat(0, 2), ocv_mat(0, 3),
            ocv_mat(1, 0), ocv_mat(1, 1), ocv_mat(1, 2), ocv_mat(1, 3),
            ocv_mat(2, 0), ocv_mat(2, 1), ocv_mat(2, 2), ocv_mat(2, 3),
            0.0, 0.0, 0.0, 1.0);
    }
    g2o::SE3Quat cConverter::toSE3Quat(const cv::Matx44d& homCV)
    {
        Eigen::Matrix<double, 3, 3> R;
        R << homCV(0, 0), homCV(0, 1), homCV(0, 2),
            homCV(1, 0), homCV(1, 1), homCV(1, 2),
            homCV(2, 0), homCV(2, 1), homCV(2, 2);

        Eigen::Matrix<double, 3, 1> t(homCV(0, 3), homCV(1, 3), homCV(2, 3));

        return g2o::SE3Quat(R, t);
    }

    cv::Matx44d cConverter::toCvMat(const g2o::SE3Quat& SE3)
    {
        Eigen::Matrix<double, 4, 4> eigMat = SE3.to_homogeneous_matrix();
        return toCvMat(eigMat);
    }

    cv::Matx44d cConverter::toCvMat(const g2o::Sim3& Sim3)
    {
        Eigen::Matrix3d eigR = Sim3.rotation().toRotationMatrix();
        Eigen::Vector3d eigt = Sim3.translation();
        double s = Sim3.scale();
        return toCvSE3(s*eigR, eigt);
    }

    cv::Matx44d cConverter::toCvMat(const Eigen::Matrix<double, 4, 4>& m)
    {
        cv::Matx44d cvMat = cv::Matx44d::eye();
        cv::eigen2cv(m, cvMat);
        return cvMat;
    }

    cv::Matx33d cConverter::toCvMat(const Eigen::Matrix3d& m)
    {
        cv::Matx33d cvMat = cv::Matx33d::eye();
        cv::eigen2cv(m, cvMat);
        return cvMat;
    }


    cv::Matx44d cConverter::toCvSE3(const Eigen::Matrix<double, 3, 3>& R,
        const Eigen::Matrix<double, 3, 1> &t)
    {
        cv::Matx44d cvMat = cv::Matx44d::eye();
        for (int i = 0; i < 3; ++i)
            for (int j = 0; j < 3; ++j)
                cvMat(i, j) = R(i, j);

        for (int i = 0; i < 3; ++i)
            cvMat(i, 3) = t(i);

        return cvMat;
    }


    Eigen::Matrix<double, 3, 1> cConverter::toVector3d(const cv::Vec4d& cvVector)
    {
        Eigen::Matrix<double, 3, 1> v;
        v << cvVector(0), cvVector(1), cvVector(2);
        return v;
    }

    Eigen::Matrix<double, 3, 1> cConverter::toVector3d(const cv::Vec3d& cvVector)
    {
        Eigen::Matrix<double, 3, 1> v;
        v << cvVector(0), cvVector(1), cvVector(2);

        return v;
    }

    Eigen::Matrix<double, 3, 3> cConverter::toMatrix3d(const cv::Matx33d& cvMat3)
    {
        Eigen::Matrix<double, 3, 3> M;

        M << cvMat3(0, 0), cvMat3(0, 1), cvMat3(0, 2),
            cvMat3(1, 0), cvMat3(1, 1), cvMat3(1, 2),
            cvMat3(2, 0), cvMat3(2, 1), cvMat3(2, 2);

        return M;
    }
    cv::Mat cConverter::toMat(const cv::Matx44d& matx44d)
    {
        cv::Mat out = cv::Mat::zeros(4, 4, CV_64FC1);
        for (int c = 0; c < 4; ++c)
            for (int r = 0; r < 4; ++r)
                out.ptr<double>(r)[c] = matx44d(r, c);
        return out;
    }

 

参考网址:

https://blog.csdn.net/u011722133/article/details/80118330

https://blog.csdn.net/piaoxuezhong/article/details/79110421

https://blog.csdn.net/u012706484/article/details/78775360

©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值