鱼眼图像的unwarping过程

鱼眼图像的unwarping过程
第一行是提取有效区域后的鱼眼图;第二行就是展开图(第二张和第四张根据需要裁剪了一部分)

#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);
}
上一篇:分布式之Redis【一】基础学习


下一篇:XGD算法设计上机考试(补充)