添加4点标定页面,兼容2点标定

master
bob.pan 4 years ago
parent 6561a10e26
commit 4855167ea7

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1020 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 943 B

@ -63,4 +63,9 @@
<file>ToolBarpic/world15.png</file>
<file>ToolBarpic/zip7.png</file>
</qresource>
<qresource prefix="/">
<file>Resource/img.png</file>
<file>Resource/lock.png</file>
<file>Resource/lock-open.png</file>
</qresource>
</RCC>

@ -2,7 +2,7 @@
#include "QZkJsonParser.h"
#include <QSettings>
#include "QApplication"
#include <opencv.hpp>
#define WHEEL_SELFDEFINE_FILE "\\user\\selfdefine.json"
#define WHEEL_SELFDEFINE_DETECTIMAGE "DetectImage"
#define WHEEL_SELFDEFINE_ALGPARA "AlgPara"//算法参数
@ -13,7 +13,7 @@
#define WHEEL_D2H_B "b"
#pragma execution_character_set("utf-8")
using namespace cv;
lpGlobalConfig::lpGlobalConfig()
: IsOnline(0), IsDetect(0), IsCheck(false)
{
@ -42,6 +42,7 @@ void lpGlobalConfig::init(QString strPath)
bRunBackRunning = jsMyself.value("runBackRnning").toBool(false);
bRunBackClosing = jsMyself.value("runBackClosing").toBool(false);//关闭页面时自动后台运行
strSysTitle = jsMyself.value("systitle").toString(QObject::tr("识别定位一体系统"));//系统标题
bUse4PointStand = jsMyself.value("use4PointStand").toBool(false);
QJsonObject algObj = jsMyself.value(WHEEL_SELFDEFINE_ALGPARA).toObject();
if (!algObj.isEmpty())
@ -207,6 +208,39 @@ void lpGlobalConfig::loadStandParam()
point2.setY(p2y);
fScale = scale;
fLength = length;
point1_4P.setX(setting.value("point1_X_4P",100).toInt());//标定点 1
point1_4P.setY(setting.value("point1_Y_4P",100).toInt());//标定点 1
point2_4P.setX(setting.value("point2_X_4P", 200).toInt());//标定点 1
point2_4P.setY(setting.value("point2_Y_4P", 200).toInt());//标定点 1
point3_4P.setX(setting.value("point3_X_4P", 300).toInt());//标定点 1
point3_4P.setY(setting.value("point3_Y_4P", 300).toInt());//标定点 1
point4_4P.setX(setting.value("point4_X_4P", 400).toInt());//标定点 1
point4_4P.setY(setting.value("point4_Y_4P", 400).toInt());//标定点 1
real_point1_4P.setX(setting.value("real_point1_X_4P", 100).toDouble());//标定点 1
real_point1_4P.setY(setting.value("real_point1_Y_4P", 100).toDouble());//标定点 1
real_point2_4P.setX(setting.value("real_point2_X_4P", 200).toDouble());//标定点 1
real_point2_4P.setY(setting.value("real_point2_Y_4P", 200).toDouble());//标定点 1
real_point3_4P.setX(setting.value("real_point3_X_4P", 300).toDouble());//标定点 1
real_point3_4P.setY(setting.value("real_point3_Y_4P", 300).toDouble());//标定点 1
real_point4_4P.setX(setting.value("real_point4_X_4P", 400).toDouble());//标定点 1
real_point4_4P.setY(setting.value("real_point4_Y_4P", 400).toDouble());//标定点 1
matxParam_4P.m11 = setting.value("m11",1).toDouble();
matxParam_4P.m21 = setting.value("m21", 0).toDouble();
matxParam_4P.dx = setting.value("dx", 0).toDouble();
matxParam_4P.m12 = setting.value("m12", 0).toDouble();
matxParam_4P.m22 = setting.value("m22", 1).toDouble();
matxParam_4P.dy = setting.value("dy", 0).toDouble();
bTransPos_4P = setting.value("TransPos").toBool();
pointXOffset_4P = setting.value("pointXoffset_4P", 0.0).toDouble();
pointYOffset_4P = setting.value("pointYoffset_4P", 0.0).toDouble();
testPoint.setX(setting.value("test_X_4P", 500).toInt());
testPoint.setY(setting.value("test_Y_4P", 500).toInt());
}
void lpGlobalConfig::saveStandParam()
@ -223,6 +257,38 @@ void lpGlobalConfig::saveStandParam()
setting.setValue("pointYoffset", pointYOffset);
setting.setValue("pointCircle", pointCircle);
setting.setValue("TransPos", bTransPos);
setting.setValue("point1_X_4P", point1_4P.x());//标定点 1
setting.setValue("point1_Y_4P", point1_4P.y());//标定点 1
setting.setValue("point2_X_4P", point2_4P.x());//标定点 1
setting.setValue("point2_Y_4P", point2_4P.y());//标定点 1
setting.setValue("point3_X_4P", point3_4P.x());//标定点 1
setting.setValue("point3_Y_4P", point3_4P.y());//标定点 1
setting.setValue("point4_X_4P", point4_4P.x());//标定点 1
setting.setValue("point4_Y_4P", point4_4P.y());//标定点 1
setting.setValue("real_point1_X_4P", real_point1_4P.x());//标定点 1
setting.setValue("real_point1_Y_4P", real_point1_4P.y());//标定点 1
setting.setValue("real_point2_X_4P", real_point2_4P.x());//标定点 1
setting.setValue("real_point2_Y_4P", real_point2_4P.y());//标定点 1
setting.setValue("real_point3_X_4P", real_point3_4P.x());//标定点 1
setting.setValue("real_point3_Y_4P", real_point3_4P.y());//标定点 1
setting.setValue("real_point4_X_4P", real_point4_4P.x());//标定点 1
setting.setValue("real_point4_Y_4P", real_point4_4P.y());//标定点 1
setting.setValue("m11", matxParam_4P.m11);
setting.setValue("m21", matxParam_4P.m21);
setting.setValue("dx", matxParam_4P.dx);
setting.setValue("m12", matxParam_4P.m12);
setting.setValue("m22", matxParam_4P.m22);
setting.setValue("dy", matxParam_4P.dy);
setting.setValue("TransPos",bTransPos_4P);
setting.setValue("pointXoffset_4P", pointXOffset_4P);
setting.setValue("pointYoffset_4P", pointYOffset_4P);
setting.setValue("test_X_4P", testPoint.x());
setting.setValue("test_Y_4P", testPoint.y());
}
void lpGlobalConfig::savePLCPara()
@ -293,6 +359,7 @@ void lpGlobalConfig::saveDeteImage()
jsMyself.insert("runBackRnning",bRunBackRunning);
jsMyself.insert("runBackClosing", bRunBackClosing);//关闭页面时自动后台运行
jsMyself.insert("systitle", strSysTitle);//系统标题
jsMyself.insert("use4PointStand", bUse4PointStand);
QJsonObject algObj;
algObj.insert("Threshold", algParam.m_AlgThres);
@ -349,6 +416,58 @@ void lpGlobalConfig::save()
QZkJsonParser::WriteJsonObject(fileMyself, jsMyself);
}
QPointF transWorldPoint(QPointF imgPoint, MatixParam param)
{
double temX = imgPoint.x() * param.m11 + imgPoint.y() * param.m21 + param.dx;
double temY = imgPoint.x() * param.m12 + imgPoint.y() * param.m22 + param.dy;
return QPointF(temX, temY);
}
MatixParam gentransform(QPolygonF srcPos, QPolygonF dstPos)
{
Point2f srcVec[4];
Point2f dstTri[4];
srcVec[0].x = srcPos.at(0).x();
srcVec[0].y = srcPos.at(0).y();
srcVec[1].x = srcPos.at(1).x();
srcVec[1].y = srcPos.at(1).y();
srcVec[2].x = srcPos.at(2).x();
srcVec[2].y = srcPos.at(2).y();
srcVec[3].x = srcPos.at(3).x();
srcVec[3].y = srcPos.at(3).y();
dstTri[0].x = dstPos.at(0).x();
dstTri[0].y = dstPos.at(0).y();
dstTri[1].x = dstPos.at(1).x();
dstTri[1].y = dstPos.at(1).y();
dstTri[2].x = dstPos.at(2).x();
dstTri[2].y = dstPos.at(2).y();
dstTri[3].x = dstPos.at(3).x();
dstTri[3].y = dstPos.at(3).y();
/// 求得仿射变换
Mat warp_mat = getAffineTransform(srcVec, dstTri);
double* pTransMat = (double*)(warp_mat.data);
double m00 = pTransMat[0];
double m10 = pTransMat[1];
double m20 = pTransMat[2];
double m01 = pTransMat[3];
double m11 = pTransMat[4];
double m21 = pTransMat[5];
MatixParam param;
param.m11 = m00;
param.m21 = m10;
param.dx = m20;
param.m12 = m01;
param.m22 = m11;
param.dy = m21;
return param;
}

@ -5,6 +5,8 @@
#include <QObject>
#include <QString>
#include <QPoint>
#include <QPointF>
#include <QPolygonF>
/*系统参数管理类 全局调用*/
typedef struct tagAlgParam {//算法参数
@ -18,7 +20,17 @@ typedef struct tagAlgParam {//算法参数
int m_Circle_EdgeWidth{ 3 };//边缘宽度
int m_Circle_ACThres{ 3 };//边缘对比度
}AlgParam;
struct MatixParam
{
double m11{ 1 };
double m21{ 0 };
double dx{ 0 };
double m12{ 0 };
double m22{ 1 };
double dy{ 0 };
};
QPointF transWorldPoint(QPointF imgPoint,MatixParam param);
MatixParam gentransform(QPolygonF srcPos, QPolygonF dstPos);
class lpGlobalConfig :public lpsingleton<lpGlobalConfig>
{
public:
@ -98,7 +110,7 @@ public:
bool bSaveSrcOKImg_value{ false };//是否保存定位NG原始图像
int tcpServerPort{ 10100 };
//坐标标定
//2点标定 坐标标定
QPoint point1;//标定点 1
QPoint point2;//标定点 2
double fScale{ 1.0 };//比例尺 长度/像素
@ -106,14 +118,30 @@ public:
double pointXOffset{ 0 };//物理标点横向偏移
double pointYOffset{ 0 };//物理标点纵向偏移
int pointCircle{ 20 };//标定点 直径
bool bTransPos{ false };
//4点标定
QPoint point1_4P;//标定点 1
QPoint point2_4P;//标定点 2
QPoint point3_4P;//标定点 3
QPoint point4_4P;//标定点 4
QPointF real_point1_4P;
QPointF real_point2_4P;
QPointF real_point3_4P;
QPointF real_point4_4P;
MatixParam matxParam_4P;
bool bTransPos_4P{ false };
double pointXOffset_4P{ 0 };//物理标点横向偏移
double pointYOffset_4P{ 0 };//物理标点纵向偏移
QPoint testPoint;
//系统相关参数
bool bRunBackRunning{ true };//启动是自动后台运行
bool bRunBackClosing{ false };//关闭页面时自动后台运行
bool bUse4PointStand{ false };//true 表示使用4点标定法
QString strSysTitle;//系统标题
bool bTransPos{ false };
AlgParam algParam;
AlgParam algParam;//算法参数
};
#endif

@ -0,0 +1,49 @@
#include "Algo.h"
#include "QPolygon"
#include <vector>
using namespace std;
Algo::Algo()
{
}
Algo::~Algo()
{
}
void Algo::translate(QPolygonF srcPos,QPolygonF dstPos)
{
Point2f srcVec[4];
Point2f dstTri[4];
srcVec[0].x = srcPos.at(0).x();
srcVec[0].y = srcPos.at(0).y();
srcVec[1].x = srcPos.at(1).x();
srcVec[1].y = srcPos.at(1).y();
srcVec[2].x = srcPos.at(2).x();
srcVec[2].y = srcPos.at(2).y();
srcVec[3].x = srcPos.at(3).x();
srcVec[3].y = srcPos.at(3).y();
dstTri[0].x = dstPos.at(0).x();
dstTri[0].y = dstPos.at(0).y();
dstTri[1].x = dstPos.at(1).x();
dstTri[1].y = dstPos.at(1).y();
dstTri[2].x = dstPos.at(2).x();
dstTri[2].y = dstPos.at(2).y();
dstTri[3].x = dstPos.at(3).x();
dstTri[3].y = dstPos.at(3).y();
/// ÇóµÃ·ÂÉä±ä»»
Mat warp_mat = getAffineTransform(srcVec, dstTri);
int a = 0;
}

@ -0,0 +1,17 @@
#ifndef _ALGO_H_
#define _ALGO_H_
#include <opencv.hpp>
#include "QPolygon"
using namespace cv;
class Algo
{
public:
Algo();
~Algo();
void translate(QPolygonF srcPos, QPolygonF dstPos);
private:
};
#endif

@ -0,0 +1,446 @@
#include "TestTransform.h"
#include <QTransform>
#include <QPainter>
#include <opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;
#define M_LOW_TOLERANCE 0.000001
void transPoints(vector<Point2d>& vec, const Matx33d& mat)
{
for (size_t i = 0; i < vec.size(); ++i)
{
Point2d p = vec[i];
Point3d tp = mat * p;
vec[i] = Point2d(tp.x / tp.z, tp.y / tp.z);
}
}
void transPoints(vector<Point2d>& vec, const Mat& mat)
{
Matx33d matx = Matx33d::eye();
Mat matx_(3, 3, CV_64FC1, matx.val);
if (mat.rows == 2 && mat.cols == 3)
{
mat.copyTo(matx_.rowRange(0, 2));
}
else if (mat.rows == 3 && mat.cols == 3)
{
mat.copyTo(matx_);
}
else
{
std::cout << "not supported transformation mat with its size as " \
<< mat.rows << "x" << mat.cols << std::endl;
return;
}
transPoints(vec, matx);
}
Matx33d affineTrans(const vector<Point2d>& src, const vector<Point2d>& dst)
{
if (dst.empty() || src.empty()) {
return Mat();
}
Point2d pc, qc;
int smallerSize = src.size() < dst.size() ? src.size() : dst.size();
for (int i = 0; i < smallerSize; i++) {
pc += src[i];
qc += dst[i];
}
pc.x /= smallerSize;
pc.y /= smallerSize;
qc.x /= smallerSize;
qc.y /= smallerSize;
Matx21d pit;
Matx12d pi;
Matx12d qi;
Matx22d spitpi = Matx22d::zeros();
Matx22d pitpi;
Matx22d pitqi;
Matx22d spitqi = Matx22d::zeros();
for (int i = 0; i < src.size() && i < dst.size(); i++) {
Point2d qpi = src[i] - pc;
Point2d qqi = dst[i] - qc;
pit(0) = qpi.x;
pit(1) = qpi.y;
pi(0) = qpi.x;
pi(1) = qpi.y;
qi(0) = qqi.x;
qi(1) = qqi.y;
pitpi = pit * pi;
spitpi = pitpi + spitpi;
pitqi = pit * qi;
spitqi = pitqi + spitqi;
}
Matx22d ispitpi;
ispitpi = spitpi.inv();
Matx22d M = ispitpi * spitqi;
double m11 = M(0, 0);
double m21 = M(0, 1);
double m12 = M(1, 0);
double m22 = M(1, 1);
Matx33d qm(m11, m12, 0, m21, m22, 0, 0, 0, 1);
Matx33d pcm(1.0, 0, -pc.x, 0, 1.0, -pc.y, 0, 0, 1);
Matx33d qcm(1.0, 0, qc.x, 0, 1.0, qc.y, 0, 0, 1);
Matx33d ret = qcm * qm*pcm;
return ret;
}
cv::Matx33d rigidTrans(const vector<Point2d>& src, const vector<Point2d>& dst,
Mat* pCenRotScaleMat = NULL)
{
if (dst.empty() || src.empty()) {
return Mat();
}
vector<double> weights(src.size(), 1.0 / src.size());
Point2d pc, qc;
double wsum = 0;
for (int i = 0; i < src.size(); i++) {
double w = 1.0 / src.size();
weights[i] = w;
pc += src[i] * w;
qc += dst[i] * w;
wsum += w;
}
pc.x /= wsum;
pc.y /= wsum;
qc.x /= wsum;
qc.y /= wsum;
double u = 0;
double u1, u2;
u1 = 0;
u2 = 0;
for (int i = 0; i < src.size() && i < dst.size(); i++) {
Point2d qpi = src[i] - pc;
Point2d qqi = dst[i] - qc;
Point2d pi(qpi.x, qpi.y);
Point2d qi(qqi.x, qqi.y);
u1 += pi.dot(qi)*weights[i];
Point2d pi_(pi.y, -pi.x);
u2 += qi.dot(pi_)*weights[i];
}
u = sqrt(u1*u1 + u2 * u2);
if (u < M_LOW_TOLERANCE) {
u = M_LOW_TOLERANCE;
}
Matx22d R = Matx22d::zeros();
Matx22d r = Matx22d::zeros();
for (int i = 0; i < src.size() && i < dst.size(); i++) {
Point2d qpi = src[i] - pc;
Point2d qqi = dst[i] - qc;
Point2d pi(qpi.x, qpi.y);
Point2d qi(qqi.x, qqi.y);
Point2d pi_(pi.y, -pi.x);
Point2d qi_(qi.y, -qi.x);
r(0, 0) = pi.dot(qi);
r(0, 1) = pi.dot(qi_);
r(1, 0) = pi_.dot(qi);
r(1, 1) = pi_.dot(qi_);
R = R + r * (weights[i] / u);
}
double m11 = R(0, 0);
double m21 = R(0, 1);
double m12 = R(1, 0);
double m22 = R(1, 1);
Matx33d qm(m11, m12, 0, m21, m22, 0, 0, 0, 1);
Matx33d pcm(1.0, 0, -pc.x, 0, 1.0, -pc.y, 0, 0, 1);
Matx33d qcm(1.0, 0, qc.x, 0, 1.0, qc.y, 0, 0, 1);
Matx33d ret = qcm * qm*pcm;
if (pCenRotScaleMat)
{
*pCenRotScaleMat = Mat(qm);
}
return ret;
}
bool cmpPointVec(const vector<Point2d>& vec0, const vector<Point2d>& vec1, const Matx33d& mat, double tor)
{
int smallerSize = vec0.size() < vec1.size() ? vec0.size() : vec1.size();
for (int i = 0; i < smallerSize; ++i)
{
Point2d p0, p1;
p0 = vec0[i];
p1 = vec1[i];
Point3d tp0 = mat * p0;
tp0.x /= tp0.z;
tp0.y /= tp0.z;
if (abs(p1.x - tp0.x) > tor || abs(p1.y - tp0.y) > tor)
{
return false;
}
}
return true;
}
void testTransSolver()
{
{
//rotation only
vector<Point2d> vec0, vec1;
vec0.push_back(Point2d());
vec0.push_back(Point2d(1, 0));
vec0.push_back(Point2d(1, 1));
vec0.push_back(Point2d(0, 1));
vec1.push_back(Point2d());
vec1.push_back(Point2d(0, 1));
vec1.push_back(Point2d(-1, 1));
vec1.push_back(Point2d(-1, 0));
Matx33d ret = affineTrans(vec0, vec1);
_ASSERTE(cmpPointVec(vec0, vec1, ret, M_LOW_TOLERANCE));
ret = rigidTrans(vec0, vec1);
_ASSERTE(cmpPointVec(vec0, vec1, ret, M_LOW_TOLERANCE));
}
{
// rotation and scale
vector<Point2d> vec0, vec1;
vec0.push_back(Point2d());
vec0.push_back(Point2d(1, 0));
vec0.push_back(Point2d(1, 1));
vec0.push_back(Point2d(0, 1));
vec1.push_back(Point2d());
vec1.push_back(Point2d(1, 1));
vec1.push_back(Point2d(0, 2));
vec1.push_back(Point2d(-1, 1));
Matx33d ret = affineTrans(vec0, vec1);
_ASSERTE(cmpPointVec(vec0, vec1, ret, M_LOW_TOLERANCE));
}
{
// scale only
vector<Point2d> vec0, vec1;
vec0.push_back(Point2d());
vec0.push_back(Point2d(1, 0));
vec0.push_back(Point2d(1, 1));
vec0.push_back(Point2d(0, 1));
vec1.push_back(Point2d());
vec1.push_back(Point2d(2, 0));
vec1.push_back(Point2d(2, 2));
vec1.push_back(Point2d(0, 2));
Matx33d ret = affineTrans(vec0, vec1);
_ASSERTE(cmpPointVec(vec0, vec1, ret, M_LOW_TOLERANCE));
}
{
// translation only
vector<Point2d> vec0, vec1;
vec0.push_back(Point2d());
vec0.push_back(Point2d(1, 0));
vec0.push_back(Point2d(1, 1));
vec0.push_back(Point2d(0, 1));
vec1.push_back(Point2d(1, 1));
vec1.push_back(Point2d(2, 1));
vec1.push_back(Point2d(2, 2));
vec1.push_back(Point2d(1, 2));
Matx33d ret = affineTrans(vec0, vec1);
_ASSERTE(cmpPointVec(vec0, vec1, ret, M_LOW_TOLERANCE));
ret = rigidTrans(vec0, vec1);
_ASSERTE(cmpPointVec(vec0, vec1, ret, M_LOW_TOLERANCE));
}
{
for (int i = 0; i < 10000; ++i)
{
// random rotation and translation
Mat mat23 = getRotationMatrix2D(Point2f(), rand() % 360, 1.0);
mat23.at<double>(0, 2) = (rand() % 1000) / 1000.0;
mat23.at<double>(1, 2) = (rand() % 1000) / 1000.0;
Matx33d matx = Matx33d::eye();
Mat mat(3, 3, CV_64FC1, matx.val);
mat23.copyTo(mat.rowRange(0, 2));
vector<Point2d> vec0, vec1;
vec0.push_back(Point2d());
vec0.push_back(Point2d(1, 0));
vec0.push_back(Point2d(1, 1));
vec0.push_back(Point2d(0, 1));
vec1 = vec0;
transPoints(vec1, matx);
Matx33d ret = affineTrans(vec0, vec1);
_ASSERTE(cmpPointVec(vec0, vec1, ret, M_LOW_TOLERANCE));
ret = rigidTrans(vec0, vec1);
_ASSERTE(cmpPointVec(vec0, vec1, ret, M_LOW_TOLERANCE));
}
}
{
// skew only
vector<Point2d> vec0, vec1;
vec0.push_back(Point2d());
vec0.push_back(Point2d(1, 0));
vec0.push_back(Point2d(1, 1));
vec0.push_back(Point2d(0, 1));
vec1.push_back(Point2d());
vec1.push_back(Point2d(1, 0));
vec1.push_back(Point2d(2, 1));
vec1.push_back(Point2d(1, 1));
Matx33d ret = affineTrans(vec0, vec1);
_ASSERTE(cmpPointVec(vec0, vec1, ret, M_LOW_TOLERANCE));
}
{
// random affine
for (int i = 0; i < 10000; ++i)
{
vector<Point2d> vec0, vec1;
vec0.push_back(Point2d());
vec0.push_back(Point2d(1, 0));
vec0.push_back(Point2d(1, 1));
vec0.push_back(Point2d(0, 1));
Matx33d trans = Matx33d::eye();
Mat mat(3, 3, CV_64FC1, trans.val);
randu(mat.rowRange(0, 2), 0, 1.0);
vec1 = vec0;
transPoints(vec1, trans);
Matx33d ret = affineTrans(vec0, vec1);
_ASSERTE(cmpPointVec(vec0, vec1, ret, M_LOW_TOLERANCE));
}
}
}
void translate(QPolygonF srcPos, QPolygonF dstPos)
{
vector<Point2d> vec0, vec1;
vec0.push_back(Point2d(srcPos.at(0).x(), srcPos.at(0).y()));
vec0.push_back(Point2d(srcPos.at(1).x(), srcPos.at(1).y()));
vec0.push_back(Point2d(srcPos.at(2).x(), srcPos.at(2).y()));
vec0.push_back(Point2d(srcPos.at(3).x(), srcPos.at(3).y()));
vec1.push_back(Point2d(dstPos.at(0).x(), dstPos.at(0).y()));
vec1.push_back(Point2d(dstPos.at(1).x(), dstPos.at(1).y()));
vec1.push_back(Point2d(dstPos.at(2).x(), dstPos.at(2).y()));
vec1.push_back(Point2d(dstPos.at(3).x(), dstPos.at(3).y()));
Matx33d ret = affineTrans(vec0, vec1);
Mat retMat = Mat(ret);
Point2f srcVec[4];
Point2f dstTri[4];
srcVec[0].x = srcPos.at(0).x();
srcVec[0].y = srcPos.at(0).y();
srcVec[1].x = srcPos.at(1).x();
srcVec[1].y = srcPos.at(1).y();
srcVec[2].x = srcPos.at(2).x();
srcVec[2].y = srcPos.at(2).y();
srcVec[3].x = srcPos.at(3).x();
srcVec[3].y = srcPos.at(3).y();
dstTri[0].x = dstPos.at(0).x();
dstTri[0].y = dstPos.at(0).y();
dstTri[1].x = dstPos.at(1).x();
dstTri[1].y = dstPos.at(1).y();
dstTri[2].x = dstPos.at(2).x();
dstTri[2].y = dstPos.at(2).y();
dstTri[3].x = dstPos.at(3).x();
dstTri[3].y = dstPos.at(3).y();
/// ÇóµÃ·ÂÉä±ä»»
Mat warp_mat = getAffineTransform(srcVec, dstTri);
double* pTransMat = (double*)(warp_mat.data);
double m00=pTransMat[0];
double m10=pTransMat[1];
double m20=pTransMat[2];
double m01=pTransMat[3];
double m11=pTransMat[4];
double m21=pTransMat[5];
int newX = 100;
int newY = 100;
double temX = newX * m00 + newY * m10 + m20;
double temY = newX * m01 + newY * m11 + m21;
int a = 0;
}
TestTransform::TestTransform(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
}
Q_SLOT void TestTransform::onButtonClicked()
{
//testTransSolver();
QPolygonF srcP;
srcP.append(QPointF(-105, -100));
srcP.append(QPointF(-204, -100));
srcP.append(QPointF(-300, -200));
srcP.append(QPointF(-200, -200));
QPolygonF dstP;
dstP.append(QPointF(-50, 50));
dstP.append(QPointF(50, 50));
dstP.append(QPointF(50, -50));
dstP.append(QPointF(-50, -50));
translate(srcP, dstP);
}
void TestTransform::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QFont font("Courier", 24);
painter.setFont(font);
painter.drawText(100, 100, "Hello, world!");
QTransform transform;
transform.rotate(15.0);
painter.setWorldTransform(transform);
painter.drawText(100, 100, "Hello, world!");
}

@ -0,0 +1,18 @@
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_TestTransform.h"
class TestTransform : public QMainWindow
{
Q_OBJECT
public:
TestTransform(QWidget *parent = Q_NULLPTR);
Q_SLOT void onButtonClicked();
protected:
virtual void paintEvent(QPaintEvent *event);
private:
Ui::TestTransformClass ui;
};

@ -0,0 +1,4 @@
<RCC>
<qresource prefix="TestTransform">
</qresource>
</RCC>

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TestTransformClass</class>
<widget class="QMainWindow" name="TestTransformClass">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>TestTransform</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>360</x>
<y>20</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="TestTransform.qrc"/>
</resources>
<connections/>
</ui>

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0AB1DDAD-DC20-4A2C-B1FE-1D122125FEE2}</ProjectGuid>
<Keyword>Qt4VSv1.0</Keyword>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">
<QtMsBuild>$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
</PropertyGroup>
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
</Target>
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
<Import Project="$(QtMsBuild)\qt.props" />
</ImportGroup>
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="Shared" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PreprocessorDefinitions>UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;E:\wheelValve\3part\opencv3.4.1\include;E:\wheelValve\3part\opencv3.4.1\include\opencv;E:\wheelValve\3part\opencv3.4.1\include\opencv2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<Optimization>Disabled</Optimization>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;E:\wheelValve\3part\opencv3.4.1\x64\vc15\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;opencv_world341d.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<QtMoc>
<OutputFile>.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</OutputFile>
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
<IncludePath>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;E:\wheelValve\3part\opencv3.4.1\include;E:\wheelValve\3part\opencv3.4.1\include\opencv;E:\wheelValve\3part\opencv3.4.1\include\opencv2;%(AdditionalIncludeDirectories)</IncludePath>
<Define>UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</Define>
</QtMoc>
<QtUic>
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
<OutputFile>.\GeneratedFiles\ui_%(Filename).h</OutputFile>
</QtUic>
<QtRcc>
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
<OutputFile>.\GeneratedFiles\qrc_%(Filename).cpp</OutputFile>
</QtRcc>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PreprocessorDefinitions>UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat />
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
<AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
<AdditionalDependencies>qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<QtMoc>
<OutputFile>.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</OutputFile>
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
<IncludePath>.\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories)</IncludePath>
<Define>UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions)</Define>
</QtMoc>
<QtUic>
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
<OutputFile>.\GeneratedFiles\ui_%(Filename).h</OutputFile>
</QtUic>
<QtRcc>
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
<OutputFile>.\GeneratedFiles\qrc_%(Filename).cpp</OutputFile>
</QtRcc>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Algo.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="TestTransform.cpp" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="TestTransform.h" />
</ItemGroup>
<ItemGroup>
<QtUic Include="TestTransform.ui" />
</ItemGroup>
<ItemGroup>
<QtRcc Include="TestTransform.qrc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Algo.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" />
</ImportGroup>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties MocDir=".\GeneratedFiles\$(ConfigurationName)" UicDir=".\GeneratedFiles" RccDir=".\GeneratedFiles" lupdateOptions="" lupdateOnBuild="0" lreleaseOptions="" Qt5Version_x0020_x64="qt5.9.4-msvc2017-x64" MocOptions="" />
</VisualStudio>
</ProjectExtensions>
</Project>

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
<Extensions>qrc;*</Extensions>
<ParseFiles>false</ParseFiles>
</Filter>
<Filter Include="Form Files">
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
<Extensions>ui</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
<Extensions>qrc;*</Extensions>
<ParseFiles>false</ParseFiles>
</Filter>
<Filter Include="Generated Files">
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
<Extensions>moc;h;cpp</Extensions>
<SourceControlFiles>False</SourceControlFiles>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TestTransform.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Algo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="TestTransform.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<QtUic Include="TestTransform.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup>
<ItemGroup>
<QtRcc Include="TestTransform.qrc">
<Filter>Resource Files</Filter>
</QtRcc>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Algo.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -0,0 +1,10 @@
#include "TestTransform.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TestTransform w;
w.show();
return a.exec();
}

@ -162,6 +162,12 @@ Q_SLOT void lpImageCaliUI::onButtonClicked()
lpGlobalConfig::instance()->fScale = scale;
lpGlobalConfig::instance()->bTransPos = ui.checkBox->isChecked();
lpGlobalConfig::instance()->saveStandParam();
ui.label_info->setText("参数已生效");
ui.label_info->setStyleSheet("background-color: rgb(250, 168, 55);");
if (m_timerID == 0)
{
m_timerID = startTimer(1000);
}
}
else if("m_pbExit" == strObj)
{

@ -0,0 +1,323 @@
#include "lpImageCaliUI4P.h"
#include <QFileDialog>
#include "lpGlobalConfig.h"
#include <QSettings>
#include <QApplication>
#pragma execution_character_set("utf-8")
lpImageCaliUI4P::lpImageCaliUI4P(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
m_srcImgView = replaceWidget<AwesomeImgViewer>(ui.widget);
connect(m_srcImgView, SIGNAL(filterroiChanged(const AwesomeRoiInfo&, QString)), this, SLOT(onROIChange(const AwesomeRoiInfo&, QString)));
connect(m_srcImgView, SIGNAL(pixelClicked(QPoint)), this, SLOT(onPixelClicked(QPoint)));
connect(m_srcImgView, SIGNAL(roiLockIng(QString)), this, SLOT(onRoiLockIng(QString)));
connect(m_srcImgView, SIGNAL(sgImageScale(qreal)), this, SLOT(onImageScale(qreal)));
connect(ui.m_pbLoadImg, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
connect(ui.m_pbApply, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
connect(ui.m_pbExit, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
connect(ui.m_pbLock, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
QString strPath = QApplication::applicationDirPath() + "/showImg.ini";//图像展示比例的参数
QSettings setting(strPath, QSettings::IniFormat);
double nScale = setting.value("ShowImg/Scale_Standard", 0.53).toDouble();
m_srcImgView->setInitScale(nScale);
}
lpImageCaliUI4P::~lpImageCaliUI4P()
{
if (m_srcImgView) {
delete m_srcImgView;
m_srcImgView = nullptr;
}
}
template<typename _Widget>
_Widget* lpImageCaliUI4P::replaceWidget(QWidget* pSrcWidget)
{
if (!pSrcWidget) {
return nullptr;
}
QWidget* pParent = qobject_cast<QWidget*>(pSrcWidget->parent());
if (!pParent) {
return nullptr;
}
_Widget* pDstWidget = new _Widget;
auto *pFrom = pParent->layout()->replaceWidget(pSrcWidget, pDstWidget);
delete pFrom;
delete pSrcWidget;
return pDstWidget;
}
void lpImageCaliUI4P::showEvent(QShowEvent *event)
{
ui.checkBox->setChecked(lpGlobalConfig::instance()->bTransPos_4P);
ui.m_lineEdit_P1X->setText(QString("%1").arg(lpGlobalConfig::instance()->point1_4P.x()));
ui.m_lineEdit_P1Y->setText(QString("%1").arg(lpGlobalConfig::instance()->point1_4P.y()));
ui.m_lineEdit_P2X->setText(QString("%1").arg(lpGlobalConfig::instance()->point2_4P.x()));
ui.m_lineEdit_P2Y->setText(QString("%1").arg(lpGlobalConfig::instance()->point2_4P.y()));
ui.m_lineEdit_P3X->setText(QString("%1").arg(lpGlobalConfig::instance()->point3_4P.x()));
ui.m_lineEdit_P3Y->setText(QString("%1").arg(lpGlobalConfig::instance()->point3_4P.y()));
ui.m_lineEdit_P4X->setText(QString("%1").arg(lpGlobalConfig::instance()->point4_4P.x()));
ui.m_lineEdit_P4Y->setText(QString("%1").arg(lpGlobalConfig::instance()->point4_4P.y()));
ui.m_lineEdit_P1X_P->setText(QString("%1").arg(lpGlobalConfig::instance()->real_point1_4P.x()));
ui.m_lineEdit_P1Y_P->setText(QString("%1").arg(lpGlobalConfig::instance()->real_point1_4P.y()));
ui.m_lineEdit_P2X_P->setText(QString("%1").arg(lpGlobalConfig::instance()->real_point2_4P.x()));
ui.m_lineEdit_P2Y_P->setText(QString("%1").arg(lpGlobalConfig::instance()->real_point2_4P.y()));
ui.m_lineEdit_P3X_P->setText(QString("%1").arg(lpGlobalConfig::instance()->real_point3_4P.x()));
ui.m_lineEdit_P3Y_P->setText(QString("%1").arg(lpGlobalConfig::instance()->real_point3_4P.y()));
ui.m_lineEdit_P4X_P->setText(QString("%1").arg(lpGlobalConfig::instance()->real_point4_4P.x()));
ui.m_lineEdit_P4Y_P->setText(QString("%1").arg(lpGlobalConfig::instance()->real_point4_4P.y()));
ui.m_lineEdit_Xoffset->setText(QString("%1").arg(lpGlobalConfig::instance()->pointXOffset_4P));
ui.m_lineEdit_Yoffset->setText(QString("%1").arg(lpGlobalConfig::instance()->pointYOffset_4P));
m_point1 = lpGlobalConfig::instance()->point1_4P;
m_point2 = lpGlobalConfig::instance()->point2_4P;
m_point3 = lpGlobalConfig::instance()->point3_4P;
m_point4 = lpGlobalConfig::instance()->point4_4P;
testPoint = lpGlobalConfig::instance()->testPoint;
QPointF tmpTestPoint = transWorldPoint(testPoint,lpGlobalConfig::instance()->matxParam_4P);
ui.label_testSrc->setText(QString("(%1,%2)").arg(testPoint.x()).arg(testPoint.y()));
ui.label_testDst->setText(QString("(%1,%2)").arg(tmpTestPoint.x()).arg(tmpTestPoint.y()));
if (m_srcImgView)
{
m_srcImgView->onClearAllROI();
QString DstPath = QApplication::applicationDirPath() + "\\user\\StandImage.png";
QImage img;
img.load(DstPath);
m_imageH = img.height();
m_imageW = img.width();
m_srcImgView->setImg(img);
AddPoint(m_point1, "P1");
AddPoint(m_point2, "P2");
AddPoint(m_point3, "P3");
AddPoint(m_point4, "P4");
AddPoint(testPoint, "TEST",QColor(255,170,0));
m_srcImgView->setLabelVisible(true);
m_srcImgView->setLockAll(true);
}
ui.m_pbLock->setText(tr("解锁"));
}
void lpImageCaliUI4P::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange)
{
ui.retranslateUi(this);
}
}
Q_SLOT void lpImageCaliUI4P::onButtonClicked()
{
QString strObj = sender()->objectName();
if (strObj == "m_pbLoadImg")
{
QString fileName = QFileDialog::getOpenFileName(this, tr("选择标定图"), "/home/jana", tr("Image Files (*.png *.jpg *.bmp)"));
if (!fileName.isEmpty())
{
QString DstPath = QApplication::applicationDirPath() + "\\user\\StandImage.png";
QString sourcePath = fileName;
DstPath.replace("\\", "/");
if (sourcePath == DstPath) {
}
if (!QFile::exists(sourcePath)) {
}
QDir *createfile = new QDir;
bool exist = createfile->exists(DstPath);
if (exist) {
createfile->remove(DstPath);
}
if (!QFile::copy(sourcePath, DstPath)) {
}
QImage img;
img.load(fileName);
if (m_srcImgView) {
m_srcImgView->setImg(img);
}
delete createfile;
createfile = nullptr;
}
}
else if ("m_pbApply" == strObj)
{
double realx1 = ui.m_lineEdit_P1X_P->text().toDouble();
double realy1 = ui.m_lineEdit_P1Y_P->text().toDouble();
double realx2 = ui.m_lineEdit_P2X_P->text().toDouble();
double realy2 = ui.m_lineEdit_P2Y_P->text().toDouble();
double realx3 = ui.m_lineEdit_P3X_P->text().toDouble();
double realy3 = ui.m_lineEdit_P3Y_P->text().toDouble();
double realx4 = ui.m_lineEdit_P4X_P->text().toDouble();
double realy4 = ui.m_lineEdit_P4Y_P->text().toDouble();
QPointF realPoint1 = QPointF(realx1, realy1);
QPointF realPoint2 = QPointF(realx2, realy2);
QPointF realPoint3 = QPointF(realx3, realy3);
QPointF realPoint4 = QPointF(realx4, realy4);
lpGlobalConfig::instance()->real_point1_4P = realPoint1;
lpGlobalConfig::instance()->real_point2_4P = realPoint2;
lpGlobalConfig::instance()->real_point3_4P = realPoint3;
lpGlobalConfig::instance()->real_point4_4P = realPoint4;
lpGlobalConfig::instance()->pointXOffset_4P = ui.m_lineEdit_Xoffset->text().toDouble();
lpGlobalConfig::instance()->pointYOffset_4P = ui.m_lineEdit_Yoffset->text().toDouble();
lpGlobalConfig::instance()->point1_4P = m_point1;
lpGlobalConfig::instance()->point2_4P = m_point2;
lpGlobalConfig::instance()->point3_4P = m_point3;
lpGlobalConfig::instance()->point4_4P = m_point4;
lpGlobalConfig::instance()->bTransPos_4P = ui.checkBox->isChecked();
lpGlobalConfig::instance()->testPoint = testPoint;
QPolygonF srcPoly;
QPolygonF dstPoly;
srcPoly << m_point1 << m_point2 << m_point3 << m_point4;
dstPoly << realPoint1 << realPoint2 << realPoint3 << realPoint4;
lpGlobalConfig::instance()->matxParam_4P = gentransform(srcPoly, dstPoly);
QPointF tmpTestPoint = transWorldPoint(testPoint, lpGlobalConfig::instance()->matxParam_4P);
ui.label_testSrc->setText(QString("(%1,%2)").arg(testPoint.x()).arg(testPoint.y()));
ui.label_testDst->setText(QString("(%1,%2)").arg(tmpTestPoint.x()).arg(tmpTestPoint.y()));
lpGlobalConfig::instance()->saveStandParam();
ui.label_info->setText("参数已生效");
ui.label_info->setStyleSheet("background-color: rgb(250, 168, 55);");
if (m_timerID == 0)
{
m_timerID = startTimer(1000);
}
}
else if ("m_pbExit" == strObj)
{
close();
}
else if ("m_pbLock" == strObj)
{
QString str = ui.m_pbLock->text();
if (str == "解锁") {
ui.m_pbLock->setText(tr("上锁"));
if (m_srcImgView)
{
m_srcImgView->setLockAll(false);
}
ui.label_info->setText("已解锁");
ui.label_info->setStyleSheet("background-color: rgb(255, 68, 55);");
if (m_timerID == 0)
{
m_timerID = startTimer(1000);
}
}
else {
if (m_srcImgView)
{
m_srcImgView->setLockAll(true);
}
ui.m_pbLock->setText(tr("解锁"));
ui.label_info->setText("已上锁");
ui.label_info->setStyleSheet("background-color: rgb(255, 68, 55);");
if (m_timerID == 0)
{
m_timerID = startTimer(1000);
}
}
}
}
Q_SLOT void lpImageCaliUI4P::onROIChange(const AwesomeRoiInfo& roiInfo, QString strID)
{
if (strID == "P1")
{
QPointF p = roiInfo.vertex.at(0);
m_point1.setX(p.x());
m_point1.setY(p.y());
ui.m_lineEdit_P1X->setText(QString("%1").arg(m_point1.x()));
ui.m_lineEdit_P1Y->setText(QString("%1").arg(m_point1.y()));
}
else if (strID == "P2")
{
QPointF p = roiInfo.vertex.at(0);
m_point2.setX(p.x());
m_point2.setY(p.y());
ui.m_lineEdit_P2X->setText(QString("%1").arg(m_point2.x()));
ui.m_lineEdit_P2Y->setText(QString("%1").arg(m_point2.y()));
}
else if (strID == "P3")
{
QPointF p = roiInfo.vertex.at(0);
m_point3.setX(p.x());
m_point3.setY(p.y());
ui.m_lineEdit_P3X->setText(QString("%1").arg(m_point3.x()));
ui.m_lineEdit_P3Y->setText(QString("%1").arg(m_point3.y()));
}
else if (strID == "P4")
{
QPointF p = roiInfo.vertex.at(0);
m_point4.setX(p.x());
m_point4.setY(p.y());
ui.m_lineEdit_P4X->setText(QString("%1").arg(m_point4.x()));
ui.m_lineEdit_P4Y->setText(QString("%1").arg(m_point4.y()));
}
else if (strID == "TEST")
{
QPointF p = roiInfo.vertex.at(0);
testPoint.setX(p.x());
testPoint.setY(p.y());
QPointF tmpTestPoint = transWorldPoint(testPoint, lpGlobalConfig::instance()->matxParam_4P);
ui.label_testSrc->setText(QString("(%1,%2)").arg(testPoint.x()).arg(testPoint.y()));
ui.label_testDst->setText(QString("(%1,%2)").arg(tmpTestPoint.x()).arg(tmpTestPoint.y()));
}
}
Q_SLOT void lpImageCaliUI4P::onPixelClicked(QPoint point)
{
int a = 0;
}
Q_SLOT void lpImageCaliUI4P::onImageScale(qreal value)
{
QString strPath = QApplication::applicationDirPath() + "/showImg.ini";
QSettings setting(strPath, QSettings::IniFormat);
QObject *obj = sender();
setting.setValue("ShowImg/Scale_Standard", value);
}
void lpImageCaliUI4P::AddPoint(QPoint &p, QString strName,QColor color)
{
if (m_srcImgView)
{
int x = p.x();
int y = p.y();
int xp = (x - m_imageW / 2);
int yp = (y - m_imageH / 2);
m_srcImgView->addPointRoi(QPointF(xp, yp), lpGlobalConfig::instance()->pointCircle, 0, strName, color, QColor(255, 0, 255));
}
}
Q_SLOT void lpImageCaliUI4P::onRoiLockIng(QString strName)
{
ui.label_info->setText("不能操作,请解锁");
ui.label_info->setStyleSheet("background-color: rgb(255, 68, 55);");
if (m_timerID == 0)
{
m_timerID = startTimer(1000);
}
}
void lpImageCaliUI4P::timerEvent(QTimerEvent *event)
{
if (m_timerID == event->timerId())
{
killTimer(m_timerID);
m_timerID = 0;
ui.label_info->setText("");
ui.label_info->setStyleSheet("");
}
}

@ -0,0 +1,48 @@
#ifndef _LPIMAGECALIUI4P_H_
#define _LPIMAGECALIUI4P_H_
#include <QWidget>
#include "ui_lpImageCaliUI4P.h"
#include "AwesomeImgViewer.h"
class lpImageCaliUI4P : public QWidget
{
Q_OBJECT
public:
lpImageCaliUI4P(QWidget *parent = Q_NULLPTR);
~lpImageCaliUI4P();
template<typename _Widget>
_Widget* replaceWidget(QWidget* pSrcWidget);
protected:
void AddPoint(QPoint &p, QString strName, QColor color = QColor(0, 255, 0));
Q_SLOT void onButtonClicked();
Q_SLOT void onROIChange(const AwesomeRoiInfo& roiInfo, QString strID);
Q_SLOT void onPixelClicked(QPoint point);
Q_SLOT void onImageScale(qreal scale);
Q_SLOT void onRoiLockIng(QString strName);
protected:
virtual void showEvent(QShowEvent *event);
virtual void changeEvent(QEvent *event);
virtual void timerEvent(QTimerEvent *event);
private:
Ui::lpImageCaliUI4P ui;
AwesomeImgViewer *m_srcImgView{ nullptr };
int m_imageH{ 0 };
int m_imageW{ 0 };
QPoint m_point1;
QPoint m_point2;
QPoint m_point3;
QPoint m_point4;
QPoint testPoint;
double m_length;
double m_scale;
int m_timerID{ 0 };
};
#endif

@ -0,0 +1,520 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>lpImageCaliUI4P</class>
<widget class="QWidget" name="lpImageCaliUI4P">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1029</width>
<height>634</height>
</rect>
</property>
<property name="windowTitle">
<string>lpImageCaliUI4P</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>9</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_info">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="title">
<string>操作</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="m_pbLoadImg">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>选择标定图像</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="7" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>物理Y方向偏移</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="m_lineEdit_Yoffset"/>
</item>
</layout>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="m_pbLock">
<property name="text">
<string>解锁</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="8" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>XY坐标输出</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>是否对换</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>物理X方向偏移</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="m_lineEdit_Xoffset"/>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>像素四点坐标:</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>P1_X</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="m_lineEdit_P1X">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>1200</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>P1_Y:</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="m_lineEdit_P1Y">
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>1200</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>P2_X:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="m_lineEdit_P2X">
<property name="text">
<string>1200</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_6">
<property name="text">
<string>P2_Y:</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="m_lineEdit_P2Y">
<property name="text">
<string>1200</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>P3_X:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="m_lineEdit_P3X">
<property name="text">
<string>1200</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_12">
<property name="text">
<string>P3_Y:</string>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLineEdit" name="m_lineEdit_P3Y">
<property name="text">
<string>1200</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>P4_X:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="m_lineEdit_P4X">
<property name="text">
<string>1200</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_14">
<property name="text">
<string>P4_Y:</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLineEdit" name="m_lineEdit_P4Y">
<property name="text">
<string>1200</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>物理4点坐标</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>P1_X:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_15">
<property name="text">
<string>P2_Y:</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="m_lineEdit_P1Y_P"/>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_17">
<property name="text">
<string>P3_Y:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>P3_X:</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>P1_Y:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="m_lineEdit_P1X_P"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>P2_X:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>P4_X:</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_19">
<property name="text">
<string>P4_Y:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="m_lineEdit_P2X_P"/>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="m_lineEdit_P3X_P"/>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="m_lineEdit_P4X_P"/>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="m_lineEdit_P2Y_P"/>
</item>
<item row="2" column="3">
<widget class="QLineEdit" name="m_lineEdit_P3Y_P"/>
</item>
<item row="3" column="3">
<widget class="QLineEdit" name="m_lineEdit_P4Y_P"/>
</item>
</layout>
</widget>
</item>
<item row="5" column="0">
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>测试点:</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="1">
<widget class="QLabel" name="label_testSrc">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>测试点像素坐标</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_testDst">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>测试点物理坐标</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>像素坐标:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>物理坐标:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="m_pbApply">
<property name="text">
<string>应用</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="m_pbExit">
<property name="text">
<string>退出</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

@ -22,9 +22,9 @@
#include "databasesql.h"
#include "lpCryptokey.h"
#define VERSION_HUB "3.0.1.6"
#define VERSION_HUB "3.0.1.7"
#define VERSION_ALG "3.0.1.4"
#define UPDATE_TIME "2021-10-11"
#define UPDATE_TIME "2021-11-04"
#pragma execution_character_set("utf-8")
#define MODEL_UI_ICON_NONE ":/image/no-img"
@ -221,6 +221,7 @@ lpMainWin::lpMainWin(QWidget *parent)
ui.tp_main_tabWidget->setCurrentIndex(0);
m_pImageCaliUI = new lpImageCaliUI();//图像标定页面
m_pImageCaliUI4P = new lpImageCaliUI4P();//图像标定页面
m_pAlgParamDlg = new QAlgParamDlg();//算法参数调试页面
connect(m_pSystemConfigUI, SIGNAL(sgUpdateInfo()), this, SLOT(setWindowTitleInfo()));//系统标题
@ -359,6 +360,11 @@ lpMainWin::~lpMainWin()
delete m_pImageCaliUI;
m_pImageCaliUI = nullptr;
}
if (m_pImageCaliUI4P)
{
delete m_pImageCaliUI4P;
m_pImageCaliUI4P = nullptr;
}
if (m_pCheckLineseUI)
{
delete m_pCheckLineseUI;
@ -763,14 +769,31 @@ void lpMainWin::IEngineResult(QVariantMap vMap)
/*中心坐标偏移值计算*/
double centerX = 0.0;
double centerY = 0.0;
if (lpGlobalConfig::instance()->bTransPos == false)
if (lpGlobalConfig::instance()->bUse4PointStand == false)
{
centerX = centerPoint.x() * lpGlobalConfig::instance()->fScale + lpGlobalConfig::instance()->pointXOffset;
centerY = centerPoint.y() * lpGlobalConfig::instance()->fScale + lpGlobalConfig::instance()->pointYOffset;
//如果标定模式使用两点标定
if (lpGlobalConfig::instance()->bTransPos == false)
{
centerX = centerPoint.x() * lpGlobalConfig::instance()->fScale + lpGlobalConfig::instance()->pointXOffset;
centerY = centerPoint.y() * lpGlobalConfig::instance()->fScale + lpGlobalConfig::instance()->pointYOffset;
}
else {
centerY = centerPoint.x() * lpGlobalConfig::instance()->fScale + lpGlobalConfig::instance()->pointXOffset;
centerX = centerPoint.y() * lpGlobalConfig::instance()->fScale + lpGlobalConfig::instance()->pointYOffset;
}
}
else {
centerY = centerPoint.x() * lpGlobalConfig::instance()->fScale + lpGlobalConfig::instance()->pointXOffset;
centerX = centerPoint.y() * lpGlobalConfig::instance()->fScale + lpGlobalConfig::instance()->pointYOffset;
else {//4点标定
QPointF tmpCenter = transWorldPoint(centerPoint, lpGlobalConfig::instance()->matxParam_4P);
if (lpGlobalConfig::instance()->bTransPos_4P == false)
{
centerX = tmpCenter.x() + lpGlobalConfig::instance()->pointXOffset_4P;
centerY = tmpCenter.y() + lpGlobalConfig::instance()->pointYOffset_4P;
}
else {
centerY = tmpCenter.x() + lpGlobalConfig::instance()->pointXOffset_4P;
centerX = tmpCenter.y() + lpGlobalConfig::instance()->pointYOffset_4P;
}
}
@ -988,14 +1011,28 @@ Q_SLOT void lpMainWin::onActionClicked()
}
}
else if ("action_ImageCali" == strObj) {
if (m_pImageCaliUI) {
m_pImageCaliUI->setParent(this);
m_pImageCaliUI->setWindowTitle(tr("图像标定"));
m_pImageCaliUI->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
m_pImageCaliUI->setWindowIcon(QIcon(":/image/leaper"));
m_pImageCaliUI->setWindowModality(Qt::ApplicationModal);
m_pImageCaliUI->setAttribute(Qt::WA_ShowModal, true);
m_pImageCaliUI->show();
if (lpGlobalConfig::instance()->bUse4PointStand == true)
{
if (m_pImageCaliUI4P) {
m_pImageCaliUI4P->setParent(this);
m_pImageCaliUI4P->setWindowTitle(tr("图像标定 4点标定"));
m_pImageCaliUI4P->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
m_pImageCaliUI4P->setWindowIcon(QIcon(":/image/leaper"));
m_pImageCaliUI4P->setWindowModality(Qt::ApplicationModal);
m_pImageCaliUI4P->setAttribute(Qt::WA_ShowModal, true);
m_pImageCaliUI4P->show();
}
}
else {
if (m_pImageCaliUI) {
m_pImageCaliUI->setParent(this);
m_pImageCaliUI->setWindowTitle(tr("图像标定 2点标定"));
m_pImageCaliUI->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
m_pImageCaliUI->setWindowIcon(QIcon(":/image/leaper"));
m_pImageCaliUI->setWindowModality(Qt::ApplicationModal);
m_pImageCaliUI->setAttribute(Qt::WA_ShowModal, true);
m_pImageCaliUI->show();
}
}
}
else if ("action_register" == strObj) {
@ -1871,6 +1908,13 @@ void lpMainWin::setMainWindowVisibility(bool state)
m_pImageCaliUI->hide();
}
}
if (m_pImageCaliUI4P)
{
if (!m_pImageCaliUI4P->isHidden())
{
m_pImageCaliUI4P->hide();
}
}
if (m_pDesigner) {
if (!m_pDesigner->IsMainFrameHidden())
{

@ -23,6 +23,7 @@
#include "CoreCtrl/CDllDesigner.h"
#include "lpdesigner.h"
#include "lpImageCaliUI.h"
#include "lpImageCaliUI4P.h"
#include "lpSystemConfigUI.h"
#include <QSystemTrayIcon>
#include "QCryptokeyUI.h"
@ -201,7 +202,7 @@ private:
lpSystemConfigUI* m_pSystemConfigUI{ nullptr };
QCamSettingDlg* m_CamSettingDlg{ nullptr };
lpImageCaliUI* m_pImageCaliUI{ nullptr };
// QPLCDevice* m_pPlcDevice{ nullptr };
lpImageCaliUI4P* m_pImageCaliUI4P{ nullptr };
QAlgParamDlg* m_pAlgParamDlg{ nullptr };//算法调参页面
private:

@ -40,6 +40,7 @@ Q_SLOT void lpSystemConfigUI::onButtonClicked()
lpGlobalConfig::instance()->bRunBackRunning = ui.checkBox_runBackRunning->isChecked();
lpGlobalConfig::instance()->bRunBackClosing = ui.checkBox_runBackClosing->isChecked();
lpGlobalConfig::instance()->strSysTitle = ui.lineEdit_4->text();
lpGlobalConfig::instance()->bUse4PointStand = ui.checkBox_4PointStand->isChecked();
lpGlobalConfig::instance()->saveDeteImage();
QString strLanguage = ui.comboBox->currentText();
@ -76,6 +77,7 @@ void lpSystemConfigUI::showEvent(QShowEvent *event)
ui.checkBox_runBackRunning->setChecked(lpGlobalConfig::instance()->bRunBackRunning);
ui.checkBox_runBackClosing->setChecked(lpGlobalConfig::instance()->bRunBackClosing);
ui.checkBox_4PointStand->setChecked(lpGlobalConfig::instance()->bUse4PointStand);
ui.lineEdit_4->setText(lpGlobalConfig::instance()->strSysTitle);
ui.lineEdit->setText(lpGlobalConfig::instance()->m_SaveImgDirPath);

@ -29,11 +29,24 @@
<rect>
<x>0</x>
<y>0</y>
<width>658</width>
<height>481</height>
<width>662</width>
<height>491</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
@ -70,6 +83,42 @@
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>系统语言设置:</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>语言</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox"/>
</item>
</layout>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
@ -111,42 +160,6 @@
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>系统语言设置:</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>语言</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox"/>
</item>
</layout>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
@ -220,17 +233,33 @@
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>视场标定方案:</string>
</property>
</spacer>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>标定选择:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_4PointStand">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>使用4点标定(默认不勾选时为2点标定)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>

@ -90,6 +90,9 @@
<ClCompile Include="GeneratedFiles\Debug\moc_lpImageCaliUI.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_lpImageCaliUI4P.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_lpImgViewer.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
@ -222,6 +225,9 @@
<ClCompile Include="GeneratedFiles\Release\moc_lpImageCaliUI.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_lpImageCaliUI4P.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_lpImgViewer.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
@ -320,6 +326,7 @@
</ClCompile>
<ClCompile Include="lpGlobalData.cpp" />
<ClCompile Include="lpImageCaliUI.cpp" />
<ClCompile Include="lpImageCaliUI4P.cpp" />
<ClCompile Include="lpMain.cpp" />
<ClCompile Include="lpMainWin.cpp" />
<ClCompile Include="lpRawTcp\lpRawTcpClientSession.cpp" />
@ -333,6 +340,16 @@
<ClCompile Include="WebServer.cpp" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="lpImageCaliUI4P.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_CORE_LIB -DTPMAIN_LIB -DTPMAIN_EXPORTS -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_SQL_LIB -DQT_PRINTSUPPORT_LIB -DQT_NETWORK_LIB -DQT_SERIALPORT_LIB -D_WINDOWS -DQT_WEBSOCKETS_LIB -D%(PreprocessorDefinitions) "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\ActiveQt" "-I$(QTDIR)\include\QtSerialPort" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtPrintSupport" "-I$(QTDIR)\include\QtSql" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtWebSockets" "-I.\..\..\src\algorithm" "-I.\..\..\src\tpMain" "-I.\..\..\src\tpMain\thread" "-I.\..\..\src\tpMain\splashScreen" "-I.\..\..\src\tpMain\LightBoxwidget" "-I.\..\..\src\tpMain\QDiskCleanThread" "-I.\..\..\src\tpMain\QPixmapListBar" "-I.\..\..\src\userCtrl" "-I.\..\..\src\NetWheel" "-I.\..\..\3part\libzkq\include" "-I.\..\..\3part\tadpole\include\tpBase" "-I.\..\..\3part\opencv3.4.1\include" "-I.\..\..\3part\opencv3.4.1\include\opencv" "-I.\..\..\3part\opencv3.4.1\include\opencv2" "-I.\..\..\3part\edcircle\include" "-I.\..\..\3part\lpCoreCtrl\include" "-I.\..\..\src\tpMain\algela" "-I.\..\..\src\ImageCompare" "-I.\..\..\src\interface" "-I.\lpRawTcp" "-I.\..\..\src\tpMain\cryptokey" "-I.\..\..\3part\RsaCrypto\include" "-I.\..\..\3part\openssl-1.0.2n\vs13\include" "-I.\..\..\3part\lp_libtcp\include"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DTPMAIN_LIB -DTPMAIN_EXPORTS -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_SQL_LIB -DQT_PRINTSUPPORT_LIB -DQT_NETWORK_LIB -DQT_SERIALPORT_LIB -DQT_WEBSOCKETS_LIB -D%(PreprocessorDefinitions) "-I." "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\ActiveQt" "-I$(QTDIR)\include\QtSerialPort" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtPrintSupport" "-I$(QTDIR)\include\QtSql" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtWebSockets" "-I.\..\..\src\algorithm" "-I.\..\..\src\tpMain" "-I.\..\..\src\tpMain\thread" "-I.\..\..\src\tpMain\splashScreen" "-I.\..\..\src\tpMain\LightBoxwidget" "-I.\..\..\src\tpMain\QDiskCleanThread" "-I.\..\..\src\tpMain\QPixmapListBar" "-I.\..\..\src\userCtrl" "-I.\..\..\src\NetWheel" "-I.\..\..\3part\libzkq\include" "-I.\..\..\3part\tadpole\include\tpBase" "-I.\..\..\3part\opencv3.4.1\include" "-I.\..\..\3part\opencv3.4.1\include\opencv" "-I.\..\..\3part\opencv3.4.1\include\opencv2" "-I.\..\..\3part\edcircle\include" "-I.\..\..\3part\lpCoreCtrl\include" "-I.\..\..\src\tpMain\algela" "-I.\..\..\src\ImageCompare" "-I.\..\..\src\interface" "-I.\lpRawTcp" "-I.\..\..\src\tpMain\cryptokey" "-I.\..\..\3part\RsaCrypto\include" "-I.\..\..\3part\openssl-1.0.2n\vs13\include" "-I.\..\..\3part\lp_libtcp\include"</Command>
</CustomBuild>
<CustomBuild Include="QAlgParamDlg.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
@ -490,6 +507,7 @@
</CustomBuild>
<ClInclude Include="..\..\src\tpMain\lpThread.h" />
<ClInclude Include="GeneratedFiles\ui_lpImageCaliUI.h" />
<ClInclude Include="GeneratedFiles\ui_lpImageCaliUI4P.h" />
<ClInclude Include="GeneratedFiles\ui_lpSystemConfigUI.h" />
<ClInclude Include="GeneratedFiles\ui_qaddmodel.h" />
<ClInclude Include="GeneratedFiles\ui_QAlgParamDlg.h" />
@ -1173,6 +1191,16 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
</CustomBuild>
<CustomBuild Include="lpImageCaliUI4P.ui">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Uic%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Uic%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\ui_%(Filename).h;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\uic.exe" -o ".\GeneratedFiles\ui_%(Filename).h" "%(FullPath)"</Command>
</CustomBuild>
<None Include="lpmain_en.ts" />
<None Include="lpmain_zh.ts" />
<CustomBuild Include="lpSystemConfigUI.ui">

@ -352,12 +352,6 @@
<ClCompile Include="QDebugDlg.cpp">
<Filter>newUI</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_QSettingDlg.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_QSettingDlg.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ImageCompare\cvdrawutils.cpp">
<Filter>ImageCompare</Filter>
</ClCompile>
@ -544,6 +538,15 @@
<ClCompile Include="GeneratedFiles\Release\moc_QAlgParamDlg.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Debug\moc_lpImageCaliUI4P.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="GeneratedFiles\Release\moc_lpImageCaliUI4P.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="lpImageCaliUI4P.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\algorithm\ImageProcess.h">
@ -675,6 +678,9 @@
<ClInclude Include="GeneratedFiles\ui_QAlgParamDlg.h">
<Filter>Generated Files</Filter>
</ClInclude>
<ClInclude Include="GeneratedFiles\ui_lpImageCaliUI4P.h">
<Filter>Generated Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\src\tpMain\QDiskCleanThread\QDiskCleanThread.h">
@ -845,6 +851,12 @@
<CustomBuild Include="QAlgParamDlg.ui">
<Filter>Form Files</Filter>
</CustomBuild>
<CustomBuild Include="lpImageCaliUI4P.h">
<Filter>Header Files</Filter>
</CustomBuild>
<CustomBuild Include="lpImageCaliUI4P.ui">
<Filter>Form Files</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<Image Include="..\..\src\tpMain\none.jpg">

@ -25,6 +25,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lpCoreCtrl", "lpCoreCtrl\lp
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Enchanter", "Enchanter\Enchanter.vcxproj", "{7B76D75A-0E01-451E-880E-FB9AC63A914B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestTransform", "TestTransform\TestTransform.vcxproj", "{0AB1DDAD-DC20-4A2C-B1FE-1D122125FEE2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -103,12 +105,18 @@ Global
{7B76D75A-0E01-451E-880E-FB9AC63A914B}.Release|x64.ActiveCfg = Release|x64
{7B76D75A-0E01-451E-880E-FB9AC63A914B}.Release|x64.Build.0 = Release|x64
{7B76D75A-0E01-451E-880E-FB9AC63A914B}.Release|x86.ActiveCfg = Release|x64
{0AB1DDAD-DC20-4A2C-B1FE-1D122125FEE2}.Debug|x64.ActiveCfg = Debug|x64
{0AB1DDAD-DC20-4A2C-B1FE-1D122125FEE2}.Debug|x64.Build.0 = Debug|x64
{0AB1DDAD-DC20-4A2C-B1FE-1D122125FEE2}.Debug|x86.ActiveCfg = Debug|x64
{0AB1DDAD-DC20-4A2C-B1FE-1D122125FEE2}.Release|x64.ActiveCfg = Release|x64
{0AB1DDAD-DC20-4A2C-B1FE-1D122125FEE2}.Release|x64.Build.0 = Release|x64
{0AB1DDAD-DC20-4A2C-B1FE-1D122125FEE2}.Release|x86.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
Qt5Version = qt5.9.4-msvc2017-x64
SolutionGuid = {CD365F32-5EAC-4A16-AD47-BFB1D8E5511A}
Qt5Version = qt5.9.4-msvc2017-x64
EndGlobalSection
EndGlobal

Binary file not shown.
Loading…
Cancel
Save