ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

鱼眼图像的unwarping过程

2021-11-06 15:03:12  阅读:207  来源: 互联网

标签:map Mat unwarping 鱼眼 IMAGE 图像 1000 cv out


请添加图片描述
第一行是提取有效区域后的鱼眼图;第二行就是展开图(第二张和第四张根据需要裁剪了一部分)

#include <iostream>
#include "opencv2/highgui/highgui.hpp"    
#include "opencv2/opencv.hpp"    
#include <opencv2/core/core.hpp>  

using namespace std;
using namespace cv;
#define IMAGE_WIDTH 1000
#define IMAGE_HEIGHT 1000
#define mode 0 //mode=0是不需要重新生成映射yml
#define FOV_240 4.188790//FOV是240°

void ExtractFish(vector<cv::Mat>& fishes) {
	for (int i = 1; i < 5; i++) {
		cv::Mat input = cv::imread("./input/" + to_string(i) + ".png", 1);
		cv::Mat mask = cv::imread("./input/Mask" + to_string(i) + ".png", 0);

		//cv::Mat mask1 = cv::Mat::zeros(mask.size(), mask.type());
		//for (int j = 0; j < mask1.rows; j++) {
		//	for (int k = 0; k < mask1.cols; k++) {
		//		if ((float)mask.at<uchar>(j, k) == 0) {
		//			mask1.at<uchar>(j, k) = (uchar)0.0;
		//		}
		//		else {
		//			mask1.at<uchar>(j, k) = (uchar)255.0;
		//		}
		//		//mask1.at<uchar>(j, k) =(uchar)(1.0 - (float)mask.at<uchar>(j, k));
		//	}
		//}
		//cv::imwrite("./out/Mask" + to_string(i) + ".png", mask1);

		cv::Mat out;
		input.copyTo(out, mask);
		cv::Mat newbg = cv::Mat::zeros(1000, 1000, CV_8UC3);
		if (i == 1) {
			resize(out, out, cv::Size(1000, 1000));
			cv::Rect rec(0, 0, out.cols, out.rows);
			out.copyTo(newbg(rec));
			resize(newbg, newbg, cv::Size(1000, 1000));
			fishes.emplace_back(newbg);
			cv::imwrite("./out/out" + to_string(i) + ".png", newbg);
		}
		else {
			resize(out, out, cv::Size(1000, 1000));
			fishes.emplace_back(out);
			cv::imwrite("./out/out" + to_string(i) + ".png", out);
		}

	}
}

void writeMatToFile(cv::Mat& m, int width, int height)
{
	std::ofstream fout("./out/step_240.yml");

	if (!fout)
	{
		std::cout << "File Not Opened" << std::endl;
		return;
	}

	int n = 0;
	int t = 0;
	fout << "%YAML:1.0" << std::endl;
	fout << "    " << "Xd: !!opencv-matrix" << std::endl;
	fout << "        " << "rows: " << width << std::endl;
	fout << "        " << "cols: " << height << std::endl;
	fout << "        " << "dt: f" << std::endl;
	fout << "        " << "data: [ ";

	for (int i = 0; i<m.cols - 1; i++)
	{
		fout << m.at<float>(0, i) << ",";
		n++;
		if (n % 10 == 0)
		{
			fout << std::endl << "            ";
		}

	}

	fout << m.at<float>(0, m.cols - 1) << "]" << std::endl;

	fout << "    " << "Yd: !!opencv-matrix" << std::endl;
	fout << "        " << "rows: " << width << std::endl;
	fout << "        " << "cols: " << height << std::endl;
	fout << "        " << "dt: f" << std::endl;
	fout << "        " << "data: [ ";

	for (int j = 0; j < m.cols - 1; j++)
	{
		fout << m.at<float>(1, j) << ",";
		t++;
		if (t % 10 == 0)
		{
			fout << std::endl << "            ";
		}
	}
	fout << m.at<float>(1, m.cols - 1) << "]" << std::endl;
}

void fish2Eqt(double x_dest, double  y_dest, double* x_src, double* y_src, double Wd)
{
	double phi1, phi2, theta1, theta2, dc, zcoor, p, _y, _z;
	double v[3];
	int theta = 20;
	double cos0 = 1.0;//俯仰角cos
	double sin0 = 0.0;//俯仰角sin

	theta1 = FOV_240 * (x_dest / Wd);//-pi to pi
	phi1 = CV_PI * (y_dest / Wd);//0 to pi

	zcoor = sin(phi1);//z
	v[0] = sin(theta1) * cos(phi1);//x
	v[1] = cos(phi1) * cos(theta1);//y

	_y = v[1] * cos0 - zcoor * sin0;
	_z = v[1] * sin0 + zcoor * cos0;

	dc = sqrt(_z * _z + v[0] * v[0]);
	theta2 = atan2(_z, v[0]);
	phi2 = atan2(dc, _y);
	p = Wd * phi2 / FOV_240;

	*x_src = p * cos(theta2);
	*y_src = p * sin(theta2);
}

void fish_2D_map(cv::Mat &map_x, cv::Mat &map_y, int Hs, int Ws)
{
	double x_d, y_d; // dest
	double x_s, y_s; // source
	double w2 = (double)Ws / 2.0 - 0.5; 
	double h2 = (double)Hs / 2.0 - 0.5; 

	Point2f temp, ttemp;
	vector<Point2f> changepoints;
	Mat fv = Mat::zeros(2, IMAGE_WIDTH*IMAGE_HEIGHT, CV_32F);
	int t = 0;
	for (int _y = 0; _y < Hs; _y++)
	{
		// y-coordinate in dest image relative to center
		y_d = (double)_y - h2;//y_d代表相对于展开图中心位置的y坐标
		for (int _x = 0; _x < Ws; _x++)
		{
			x_d = (double)_x - w2;//x_d代表相对于展开图中心位置的x坐标
			// Convert fisheye coordinate to cartesian coordinate (equirectangular)
			fish2Eqt(x_d, y_d, &x_s, &y_s, Ws);

			//cout << x_d << endl;

			x_s += w2;
			y_s += h2;

			// Create map
			map_x.at<float>(_y, _x) = float(x_s);
			map_y.at<float>(_y, _x) = float(y_s);
			//map_x map_y是鱼眼展开图对应原鱼眼图xy位置		

			fv.at<float>(0, t) = x_s;
			fv.at<float>(1, t) = y_s;
			if (t < IMAGE_WIDTH*IMAGE_HEIGHT) {
				t++;
			}
		}
	}

	writeMatToFile(fv, IMAGE_WIDTH, IMAGE_HEIGHT);
}

vector<cv::Mat> Unwarping(vector<cv::Mat>& fishes) {

	cv::Rect rect(0, 0, 1000, 1000);
	cv::Mat mls_map_x, mls_map_y;
	cv::Mat map_x, map_y;
	map_x = cv::Mat(IMAGE_HEIGHT, IMAGE_WIDTH, CV_32FC1);
	map_y = cv::Mat(IMAGE_HEIGHT, IMAGE_WIDTH, CV_32FC1);
	cv::Mat remapped[4];
	vector<cv::Mat> vectorremapped;
	cv::Mat Crop_remapped[4];
	if (mode == 0) {
		cv::FileStorage fs("./out/step_240.yml", cv::FileStorage::READ);
		fs["Xd"] >> mls_map_x;
		fs["Yd"] >> mls_map_y;
		fs.release();
	}
	for (int i = 0; i < fishes.size(); i++) {
		//需要重新生成yml时就取消fish_2D_map,注释remap。
		if (mode == 1) {
			fish_2D_map(map_x, map_y, IMAGE_HEIGHT, IMAGE_WIDTH);
		}
		else
		{
			remap(fishes[i], remapped[i], mls_map_x, mls_map_y, INTER_AREA, BORDER_CONSTANT, Scalar(0, 0, 0, 0));
			imwrite("./out/Unwarp/" + to_string(i) + ".jpg", remapped[i]);
		}
		vectorremapped.emplace_back(remapped[i]);
	}

	return vectorremapped;
}

void main() {
	vector<cv::Mat> fishes;
	//根据掩膜抠出图像有效区域并重置大小
	ExtractFish(fishes);
	//图像展开
	vector<cv::Mat> unwarpFish = Unwarping(fishes);
}

标签:map,Mat,unwarping,鱼眼,IMAGE,图像,1000,cv,out
来源: https://blog.csdn.net/qq_41598072/article/details/121179006

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有