《计算机视觉中的多视几何》代码2.21(基本类的构建,交点,两点确定的直线求解与可视化)

 用到的头文件

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

  先构建一个齐次坐标的类,在私有成员变量中加入两个bool类型的isPoint与isLine零个成员变量以判断这个齐次坐标是点还是线(这个有点麻烦,后续可能优化);

  在类中包含了对齐次坐标的检查check函数,防止输入时两个bool值都为1或0;

  包含了regulation函数,方便对点或线(不必要)的归一化方法,这样有助于 后续算法的计算,以及对点显示;

  包含了draw函数,可以在给定的任意画布中显示齐次坐标所显示的点或线,并对异常特殊显示;

class Coordinates2d
{
public:
	Coordinates2d() :x(0), y(0), isPoint(0), isLine(0) { cout << "无参构造函数" << endl; }
	Coordinates2d(int x, int y, bool a, bool b) :x(x), y(y), isPoint(a), isLine(b) { cout << "有参构造函数" << endl; }
	Coordinates2d(int x, int y, int z, bool a, bool b) :x(x), y(y), z(z), isPoint(a), isLine(b) { cout << "有参构造函数" << endl; }
	Coordinates2d(const Coordinates2d& p) {
		x = p.x;
		y = p.y;
		z = p.z;
		isPoint = p.isPoint;
		isLine = p.isLine;
		cout << "复制构造函数" << endl;
	}
	~Coordinates2d() { cout << "析构函数" << endl; }
	inline float getX() { return x; }
	inline float getY() { return y; }
	inline float getZ() { return z; }
	//统一输出,方便后续检查
	inline void print() {
		cout << "x=" << x << endl;
		cout << "y=" << y << endl;
		cout << "z=" << z << endl;
		cout << "这是:" << PointOrLine() << endl;
	}
	//点return 0,线return 1,异常return -1;
	inline int check() {
		if ((isPoint ^ isLine) == 0) { return -1; }
		else if (isLine == 1) { return 1; }
		else { return 0; }
	};
	//以中文返回,好看一点
	inline string PointOrLine() {
		if (check() == -1) { return "啥也不是"; }
		else if (check() == 0) { return "点"; }
		else { return "线"; }
	}
	//将齐次坐标归一化
	void regulation() {
		if (check() != -1 && z != 1 && z != 0) {
			x = x / z;
			y = y / z;
			z = 1.0;
		}
		else if (check() == -1) { cout << "点线不明确" << endl; }
		else { cout << "不能regulation" << endl; }
	};
	//画绿色的点与红色的线;
	void draw(Mat& background) {
		if (check() == -1) {
			cv::Point pt(background.cols/10, background.rows/2);
			cv::putText(background, "Warning!!!", pt, 1, 5, cv::Scalar(128, 128, 128),2,8);
		}
		else if (check() == 0) {
			cv::Point pt(x/z, y/z);
			cv::circle(background, pt, 3, cv::Scalar(0, 255, 0), -1);
		}
		else { 
			cv::Point pt1( -z/x,0);
		    cv::Point pt2((-z-background.rows*y)/x, background.rows);
			cout << pt1 << endl;
			cout << pt2 << endl;
			cv::line(background, pt1,pt2, cv::Scalar(0, 0, 255), 1);
		}
	}
private:
	float x;
	float y;
	float z = 1.0;
	bool isPoint;
	bool isLine;
};

求解两直线的交点的齐次坐标函数

//检查输入两线,返回点
Coordinates2d jiaodian(Coordinates2d& co1, Coordinates2d& co2)
{
	if (0 == co1.getX() * co2.getY() - co1.getY() * co2.getX()) { cout << "两条平行线没有交点!!!!" << endl; }
	else if (co1.check() == 1 && co2.check() == 1) {
		float x = co1.getY() * co2.getZ() - co1.getZ() * co2.getY();
		float y = -co1.getX() * co2.getZ() + co1.getZ() * co2.getX();
		float z = co1.getX() * co2.getY() - co1.getY() * co2.getX();
		Coordinates2d res(x, y, z, 1, 0);
		res.regulation();
		return res;
	}
	else {
		cout << "输入有误!!!!!!!!" << endl;
	}
}

求解两点所确定的直线的齐次坐标函数

//检查输入两点,返回线
Coordinates2d jiaoxian(Coordinates2d& co1, Coordinates2d& co2)
{
	if ((co1.getX() / co2.getX() == co1.getY() / co2.getY()) && (co1.getX() / co2.getX() == co1.getZ() / co2.getZ())) { cout << "同一个点无法确定唯一直线!!!!" << endl; }
	else if (co1.check() == 0 && co2.check() == 0) {
		float x = co1.getY() * co2.getZ() - co1.getZ() * co2.getY();
		float y = -co1.getX() * co2.getZ() + co1.getZ() * co2.getX();
		float z = co1.getX() * co2.getY() - co1.getY() * co2.getX();
		Coordinates2d res(x, y, z, 0, 1);
		return res;
	}
	else {
		cout << "输入有误!!!!!!!!" << endl;
	}
}

主函数部分1:给定两条直线,求解交点,并做图

int main() {
	Coordinates2d co1(300, -100, 3, 0, 1);
	Coordinates2d co2(200, -80, 400, 0, 1);
	Coordinates2d co3 = jiaodian(co1, co2);

	co3.print();//输出信息

	cv::Mat a(480, 640, CV_8UC3, cv::Scalar(0, 0, 0));//创造一个 480×640的黑布
	co1.draw(a);
	co2.draw(a);
	co3.draw(a);

	cv::imshow("reslt",a);
    cv:waitKey(0);
}

 主函数部分2:给定两个点,求解确定的直线,并做图

int main() {
	Coordinates2d co1(300, 100, 1, 1, 0);
	Coordinates2d co2(200, 80, 4, 1, 0);
	Coordinates2d co3 = jiaoxian(co1, co2);

	co3.print();//输出信息

	cv::Mat a(480, 640, CV_8UC3, cv::Scalar(0, 0, 0));//创造一个 480×640的黑布
	co1.draw(a);
	co2.draw(a);
	co3.draw(a);

	cv::imshow("reslt",a);
    cv:waitKey(0);
}

 主函数部分3:给定异常的值时(比如两线求交线,两点求交点时,或者直接无法判断时点 还是线时),生成warning图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值