cpencv笔记4.1

cpencv笔记4.1,第1张

C++读取txt
yang and me
封装了两个函数,不知是不是鸡肋,因为需要两次打开文件
(yang tell me 不鸡肋,确实该这样)

#define _CRT_SECURE_NO_WARNINGS
#include  
#include 
#include 
#include   
#include   

using namespace cv;
using namespace std;
String BASE = "miao-db/labels/train2017/";

int Get_Matrow(String s) {//封装了一个函数,读取行数
	ifstream fin;
	int i = -1;//循环多走一遍,初始值设置-1,最后可返回矩阵行数
	string str;
	fin.open(BASE + s);
	while (!fin.eof())
	{
		getline(fin, str);
		i++;
	}
	fin.close();
	return i;
}

void readfile(String s,Mat &data) {//转变为Mat存取
	double aa[100][5];
	String path = BASE + s;
	FILE* fp = fopen(path.c_str(), "r");
	int idx = 0;
	int tmp = 0;
	while (!feof(fp)) {
		double* p = aa[idx];
		int ret = fscanf(fp, "%lf %lf %lf %lf %lf", &p[0], &p[1], &p[2], &p[3], &p[4]);
		if (ret < 5) {
			break;
		}
		idx++;
	}
	fclose(fp);
	for (int i = 0; i < idx; i++) 
		for (int j = 0; j < 5; j++) 
			data.at<double>(i, j) = aa[i][j];
}

int main()
{
//不封装函数,直接读取:
	Mat date = Mat::zeros(Get_Matrow("0104.txt"), 5, CV_64F);
	readfile("0104.txt", date);
	cout << date<<endl;
	
	double aa[100][5];
	String path = BASE + "0104.txt";
	FILE* fp = fopen(path.c_str(), "r");
	int idx = 0;
	int tmp = 0;
	while (!feof(fp)) {
		double* p = aa[idx];
		int ret = fscanf(fp,"%lf %lf %lf %lf %lf",  &p[0], &p[1], &p[2], &p[3],&p[4]);
		if (ret < 5) {
			break;
		}
		idx++;
	}
	fclose(fp);
	Mat data = Mat::zeros(idx, 5, CV_64F);

	for (int i = 0; i < idx; i++) {
		for (int j = 0; j < 5; j++) {
			printf("%lf ", aa[i][j]);
			data.at<double>(i,j) = aa[i][j];//具体读取某个数字用at函数
		}
		printf("\n");
	}

	cout << data << endl;
	//读取最大最小值:
	double max, min;
	cv::Point min_loc, max_loc;
	cv::minMaxLoc(data, &min, &max, &min_loc, &max_loc);
	cout << " max = " << max << "min = " << min << endl;
	
	return 0;
}

Mat类型读取均值、最大最小值及下标

	Mat D3 = Mat::zeros(4, 3,CV_32F)+ 5.0;
	Mat a = Mat::zeros(4, 3, CV_64F)-3; //定义三行两列0填充的64位有符号数  -3 用-3填充

	Mat mean;
	Mat stddev;
	meanStdDev(a, mean, stddev);  //mean –> 均值,stddev –> 标准差
	cout << mean<<endl;
	
	//取1行1列的数   c只能用Mat类型接收
	Mat c = a.row(1).col(1); 
	
	//最大最小值
	double max, min;
	cv::Point min_loc, max_loc;
	cv::minMaxLoc(a, &min, &max, &min_loc, &max_loc);
	cout << " max = " << max << "min = " << min << endl;
	cout << " max下标 = " << max_loc << endl;

Mat最大最小值可用于单行单列求最大最小值及其下标,输出结果会有不同。



在进行行求行min下标时

double max, min;
	cv::Point min_loc, max_loc;
	cv::minMaxLoc(A.row(0), &min, &max, &min_loc, &max_loc);

输出结果
对于得到某一行的最小值坐标即:
(改行行号,min_loc.x)
取改行行号作为x,min_loc.x作为y

对于某列求min

double max, min;
	cv::Point min_loc, max_loc;
	cv::minMaxLoc(A.col(0), &min, &max, &min_loc, &max_loc);


对于得到某一列的最小值坐标即:
(min_loc.y,该列列号)
取min_loc.y作为x,该列列号作为y

Mat类型的赋值

1、可以使用A.at(i, j)进行赋值,参考读取txt赋值到Mat
2、可以直接整行,整列赋值,前提是要赋值的行列数相同,例如给某行赋值,其列数需要相等

例如:3行5列(将某一行同时赋值)
可以赋值》》》》3行5列
可以赋值》》》》2行5列

不可以赋值》》》3行4列
赋值会失效,但是不会报错,会原样输出3行4列的原矩阵数据!!!!!!!!!



某一列的均值

Mat mean_x, stddev_x, mean_y, stddev_y;
	meanStdDev(R.col(0), mean_x, stddev_x);

Mat类型的比较

两个Mat类型不直接比较


无语了
使用at函数调用才能对比,实现int类型与Mat类型的转换,哪怕Mat只有一个元素,也不可以直接使用。


if (stddev_x.at<double>(0, 0) > stddev_y.at<double>(0, 0))

OpenCV排序函数
cv::sort 负责返回排序后的矩阵

cv::sort(InputArray src,OutputArray dst,int flags);

src是排序前的Mat 矩阵,dst是排序后的Mat矩阵,flag是按照什么进行排序,如下,定义的OpenCv常量

定义OpencV常量

#define CV_SORT_EVERY_ROW    0
#define CV_SORT_EVERY_COLUMN 1
#define CV_SORT_ASCENDING    0
#define CV_SORT_DESCENDING   16

CV_SORT_EVERY_ROW + CV_SORT_ASCENDING:对矩阵的每行按照升序排序;
CV_SORT_EVERY_ROW + CV_SORT_DESCENDING:对矩阵的每行按照降序排序;
CV_SORT_EVERY_COLUMN + CV_SORT_ASCENDING:对矩阵的每列按照升序排序;
CV_SORT_EVERY_COLUMN + CV_SORT_DESCENDING:对矩阵的每列按照降序排序;

cv::sort(R,R1, SORT_EVERY_COLUMN + SORT_DESCENDING);


排序是全排列,对每一行或者每一列都按照某个标准进行排序。


不是按照维度排序,所以若想按照某一列进行排序,需要自己写一个函数。


通过某一列进行排序,函数!!!

void sortMat(Mat &stats, int colId){
    //根据指定列以行为单位排序
    
    Mat sorted_index;
    cv::sortIdx(stats, sorted_index, cv::SORT_EVERY_COLUMN + cv::SORT_DESCENDING);
    // 注意此处是DESCENDING 如果要升序需要改成ASCENDING
    
    sorted_index = sorted_index.col(colId);
    Mat sorted_stats = stats.clone();
    int row_num = sorted_index.rows;
    for(int i = 0; i < row_num; i++){
        int _idx = sorted_index.at<int>(i, 0);
        sorted_stats.row(i) = stats.row(_idx) + 0;//必须加0否则会出很难debug的错误
    }
    stats = sorted_stats;
    return;
}


今日进度:对于调用,暂存一下代码:

int idex = Get_Matrow("0001.txt");//获取要读的编号
	Mat date = Mat::zeros(idex, 5, CV_64F);//建立模具承载读的文件
	Mat A = Mat::zeros(idex, 4, CV_64F);//建立模具承载需要的数据
	Readfile("0001.txt", date);//读文件放在模具
	translate(date, A);//转换为需要的数据放在模具

	int idex2 = Get_Matrow("0002.txt");
	Mat date2 = Mat::zeros(idex2, 5, CV_64F);
	Mat B = Mat::zeros(idex2, 4, CV_64F);
	Readfile("0002.txt", date2);
	cout << "0002.txt = " << endl;
	translate(date2, B);

	Mat D = Mat::zeros(A.rows, B.rows, CV_64F);
	distBB(A, B, D);

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/562756.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-02
下一篇 2022-04-02

发表评论

登录后才能评论

评论列表(0条)

保存