opencv_mv/QPlugins/GeometryTools/FindLine/frmFindLine.cpp

876 lines
29 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "frmFindLine.h"
#include <QMessageBox>
#include <QColorDialog>
#include <QDesktopWidget>
#include "BaseItem.h"
#include <QGraphicsOpacityEffect>
#define M_PI 3.14159265358979323846
frmFindLine::frmFindLine(QString toolName, QToolBase* toolBase, QWidget* parent)
: Toolnterface(toolName, toolBase, parent)
{
ui.setupUi(this);
toolTitleName = toolName;
//FramelessWindowHint属性设置窗口去除边框
//WindowMinimizeButtonHint 属性设置在窗口最小化时,点击任务栏窗口可以显示出原窗口
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);
//设置窗体在屏幕中间位置
QDesktopWidget* desktop = QApplication::desktop();
move((desktop->width() - this->width()) / 2, (desktop->height() - this->height()) / 2);
//设置窗口背景透明
setAttribute(Qt::WA_TranslucentBackground);
this->setWindowIcon(QIcon(":/resource/find_line.png"));
//初始化标题栏
initTitleBar();
//图像显示
view = new QGraphicsViews;
ui.imageLayout->addWidget(view);
ui.btnRoiColor->setStyleSheet("background-color: rgb(0, 0, 255)");
color = QColor(0, 0, 255);
caliper_item = new Caliper(10, 160, 200, 160, 300);
//父类如果有样式表,背景色设置方法
QGraphicsOpacityEffect* e = new QGraphicsOpacityEffect(this);
e->setOpacity(0.5);
ui.txtMsg->setGraphicsEffect(e);
}
frmFindLine::~frmFindLine()
{
view->deleteLater();
caliper_item->deleteLater();
this->deleteLater();
}
void frmFindLine::initTitleBar()
{
m_titleBar = new MyTitleBar(this);
m_titleBar->move(0, 0);
connect(m_titleBar, SIGNAL(signalButtonCloseClicked()), this, SLOT(onButtonCloseClicked()));
m_titleBar->setStyleSheet("background-color: rgba(178, 178, 178,0);color:white;font-size:16px");
m_titleBar->setTitleIcon(":/resource/find_line.png");
m_titleBar->setTitleContent(toolTitleName);
m_titleBar->setButtonType(ONLY_CLOSE_BUTTON);
m_titleBar->setTitleWidth(this->width());
}
void frmFindLine::paintEvent(QPaintEvent* event)
{
//设置背景色
QPainter painter(this);
QPainterPath pathBack;
pathBack.setFillRule(Qt::WindingFill);
pathBack.addRoundedRect(QRect(0, 0, this->width(), this->height()), 3, 3);
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
painter.fillPath(pathBack, QBrush(QColor(160, 160, 160)));
return QWidget::paintEvent(event);
}
void frmFindLine::onButtonCloseClicked()
{
view_points = false;
this->close();
}
int frmFindLine::Execute(const QString toolname)
{
bool link_state = false;
image_index = 0;
QString str = ui.txtLinkImage->text();
strs.reserve(100);
strs.clear();
strs = str.split(".");
if (strs.size() == 1)
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -1;
}
for (int i = 0; i < GetToolBase()->m_Tools.size(); i++)
{
if (GetToolBase()->m_Tools[i].PublicToolName == strs[0])
{
//获取的图像在工具数组中的索引
image_index = i;
link_state = true;
}
if (GetToolBase()->m_Tools[i].PublicToolName == toolname)
{
//工具在工具数组中的索引
tool_index = i;
}
}
if (link_state == false)
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -2;
}
int result = RunToolPro();
if (result == -1)
{
return -1;
}
return 0;
}
int frmFindLine::RunToolPro()
{
try
{
srcImage = GetToolBase()->m_Tools[image_index].PublicImage.OutputImage;
k = 0;
b = 0;
dstImage = cv::Mat();
dstRoiImage = cv::Mat();
srcImage.copyTo(dstImage);
if (caliper_item->caliper_init_state == false)
{
return -1;
}
caliper_item->GetCaliper(caliper_p);
for (int i = 0; i < caliper_item->line_small_points.size(); i++)
{
if (caliper_item->line_big_points[i].x() < 0 || caliper_item->line_small_points[i].x() < 0 || caliper_item->line_big_points[i].y() < 0 || caliper_item->line_small_points[i].y() < 0)
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -1;
}
if (caliper_item->line_big_points[i].x() > dstImage.cols || caliper_item->line_small_points[i].x() > dstImage.cols || caliper_item->line_big_points[i].y() > dstImage.rows || caliper_item->line_small_points[i].y() > dstImage.rows)
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -1;
}
}
line_small_points.clear();
line_big_points.clear();
switch (ui.comboScanDirection->currentIndex()) {
case 0:
scan_direction = 0;
line_small_points = caliper_item->line_small_points;
line_big_points = caliper_item->line_big_points;
break;
case 1:
scan_direction = 1;
line_big_points = caliper_item->line_small_points;
line_small_points = caliper_item->line_big_points;
break;
case 2:
scan_direction = 0;
line_small_points = caliper_item->line_small_points;
line_big_points = caliper_item->line_big_points;
break;
case 3:
scan_direction = 1;
line_big_points = caliper_item->line_small_points;
line_small_points = caliper_item->line_big_points;
break;
}
switch (ui.comboGrayDirection->currentIndex()) {
case 0:
direction = 0;
break;
case 1:
direction = 1;
break;
}
xy.clear();
//位置跟随
if (ui.checkUseFollow->isChecked() == true)
{
strs.clear();
strs = ui.txtLinkFollow->text().split(".");
if (strs.size() == 1)
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -1;
}
bool link_state = false;
int f_index = 0;
for (int i = 0; i < GetToolBase()->m_Tools.size(); i++)
{
if (GetToolBase()->m_Tools[i].PublicToolName == strs[0])
{
f_index = i;
link_state = true;
}
}
if (link_state == false)
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -2;
}
if (strs[1] == "匹配基准中心")
{
if (GetToolBase()->m_Tools[f_index].PublicTPosition.Center.size() == 0)
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -1;
}
match_origin_point = GetToolBase()->m_Tools[f_index].PublicTPosition.DatumCenter;
match_origin_angle = 0;
match_current_point = GetToolBase()->m_Tools[f_index].PublicTPosition.Center[0];
match_current_angle = GetToolBase()->m_Tools[f_index].PublicTPosition.Angle[0];
for (int p = 0; p < line_small_points.size(); p++)
{
cv::Point2f point_small_buf = cv::Point2f(line_small_points[p].x(), line_small_points[p].y());
cv::Point2f point_small = AffineTransformPoint(match_origin_point, 0, match_current_point, match_current_angle, point_small_buf);
line_small_points[p] = QPointF(point_small.x, point_small.y);
cv::Point2f point_big_buf = cv::Point2f(line_big_points[p].x(), line_big_points[p].y());
cv::Point2f point_big = AffineTransformPoint(match_origin_point, 0, match_current_point, match_current_angle, point_big_buf);
line_big_points[p] = QPointF(point_big.x, point_big.y);
}
}
else
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -2;
}
}
int result = FindBorderPoints(dstImage, line_small_points, line_big_points, xy, ui.spinThreshold->value(), direction, scan_direction, ui.spinSegment->value());
if (result == -1)
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -1;
}
//拟合直线
vector<cv::Point2f> new_xy(xy.size());
for (int i = 0; i < xy.size(); i++)
{
new_xy[i].x = xy[i].x();
new_xy[i].y = xy[i].y();
}
int w = srcImage.cols;
cv::Vec4f fitline;
cv::fitLine(new_xy, fitline, cv::DIST_L2, 0, 0.01, 0.01);
float vx = fitline[0];
float vy = fitline[1];
float x = fitline[2];
float y = fitline[3];
double x1_1 = w - 1;
double y1_1 = (w - x) * vy / vx + y;
double x1_2 = 0;
double y1_2 = (-x * vy / vx) + y;
//剔除点
select_xy.clear();
cull_xy.clear();
for (int i = 0; i < new_xy.size(); i++)
{
//计算点到直线的距离
double distance = GetDistP2L(new_xy[i], cv::Point2f(x1_1, y1_1), cv::Point2f(x1_2, y1_2));
if (distance > ui.spinCullDistance->value())
{
cull_xy.push_back(new_xy[i]);
}
else
{
select_xy.push_back(new_xy[i]);
}
}
//剔除点后再次拟合直线
cv::fitLine(select_xy, fitline, cv::DIST_L2, 0, 0.01, 0.01);
if (dstImage.channels() == 1)
{
cv::cvtColor(dstImage, dstImage, cv::COLOR_GRAY2BGR);
}
else if (dstImage.channels() == 4)
{
cv::cvtColor(dstImage, dstImage, cv::COLOR_RGBA2BGR);
}
vx = fitline[0];
vy = fitline[1];
x = fitline[2];
y = fitline[3];
k = vy / vx;
b = y - k * x;
int y1 = int((-x * vy / vx) + y);
int y2 = int((w - x) * vy / vx + y);
cv::line(dstImage, cv::Point((w - 1), y2), cv::Point(0, y1), cv::Scalar(255, 10, 10), 1);
if (ui.checkViewROI->isChecked() == true)
{
dstRoiImage = dstImage.clone();
if (dstRoiImage.channels() == 1)
{
cv::cvtColor(dstRoiImage, dstRoiImage, cv::COLOR_GRAY2BGR);
}
else if (dstRoiImage.channels() == 4)
{
cv::cvtColor(dstRoiImage, dstRoiImage, cv::COLOR_RGBA2BGR);
}
GetToolBase()->m_Tools[tool_index].PublicImage.Name = "ROI图像";
for (int i = 0; i < line_small_points.size(); i++)
{
cv::line(dstRoiImage, cv::Point(line_small_points[i].x(), line_small_points[i].y()), cv::Point(line_big_points[i].x(), line_big_points[i].y()), cv::Scalar(223, 231, 255), 1);
}
for (int n = 0; n < select_xy.size(); n++)
{
cv::line(dstRoiImage, cv::Point(select_xy[n].x - cos(45 * M_PI / 180) * ui.spinCrossL->value(), select_xy[n].y - sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Point(select_xy[n].x + cos(45 * M_PI / 180) * ui.spinCrossL->value(), select_xy[n].y + sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Scalar(211, 0, 141), ui.spinRoiW->value());
cv::line(dstRoiImage, cv::Point(select_xy[n].x - cos(45 * M_PI / 180) * ui.spinCrossL->value(), select_xy[n].y + sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Point(select_xy[n].x + cos(45 * M_PI / 180) * ui.spinCrossL->value(), select_xy[n].y - sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Scalar(211, 0, 141), ui.spinRoiW->value());
}
for (int n = 0; n < cull_xy.size(); n++)
{
cv::line(dstRoiImage, cv::Point(cull_xy[n].x - cos(45 * M_PI / 180) * ui.spinCrossL->value(), cull_xy[n].y - sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Point(cull_xy[n].x + cos(45 * M_PI / 180) * ui.spinCrossL->value(), cull_xy[n].y + sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Scalar(0, 0, 255), ui.spinRoiW->value());
cv::line(dstRoiImage, cv::Point(cull_xy[n].x - cos(45 * M_PI / 180) * ui.spinCrossL->value(), cull_xy[n].y + sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Point(cull_xy[n].x + cos(45 * M_PI / 180) * ui.spinCrossL->value(), cull_xy[n].y - sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Scalar(0, 0, 255), ui.spinRoiW->value());
}
cv::RotatedRect rrect = cv::RotatedRect(cv::Point2f(caliper_p.col, caliper_p.row), cv::Size2f(caliper_p.len1, caliper_p.len2), -(caliper_p.angle * 180 / M_PI));
cv::Point2f vertices[4];
rrect.points(vertices);
if (ui.checkUseFollow->isChecked() == true)
{
cv::Point2f point_1 = AffineTransformPoint(match_origin_point, 0, match_current_point, match_current_angle, vertices[0]);
cv::Point2f point_2 = AffineTransformPoint(match_origin_point, 0, match_current_point, match_current_angle, vertices[1]);
cv::Point2f point_3 = AffineTransformPoint(match_origin_point, 0, match_current_point, match_current_angle, vertices[2]);
cv::Point2f point_4 = AffineTransformPoint(match_origin_point, 0, match_current_point, match_current_angle, vertices[3]);
cv::line(dstRoiImage, point_1, point_2, cv::Scalar(color.blue(), color.green(), color.red()), ui.spinRoiW->value());
cv::line(dstRoiImage, point_2, point_3, cv::Scalar(color.blue(), color.green(), color.red()), ui.spinRoiW->value());
cv::line(dstRoiImage, point_3, point_4, cv::Scalar(color.blue(), color.green(), color.red()), ui.spinRoiW->value());
cv::line(dstRoiImage, point_1, point_4, cv::Scalar(color.blue(), color.green(), color.red()), ui.spinRoiW->value());
}
else
{
cv::line(dstRoiImage, cv::Point(vertices[0].x, vertices[0].y), cv::Point(vertices[1].x, vertices[1].y), cv::Scalar(color.blue(), color.green(), color.red()), ui.spinRoiW->value());
cv::line(dstRoiImage, cv::Point(vertices[0].x, vertices[0].y), cv::Point(vertices[3].x, vertices[3].y), cv::Scalar(color.blue(), color.green(), color.red()), ui.spinRoiW->value());
cv::line(dstRoiImage, cv::Point(vertices[1].x, vertices[1].y), cv::Point(vertices[2].x, vertices[2].y), cv::Scalar(color.blue(), color.green(), color.red()), ui.spinRoiW->value());
cv::line(dstRoiImage, cv::Point(vertices[2].x, vertices[2].y), cv::Point(vertices[3].x, vertices[3].y), cv::Scalar(color.blue(), color.green(), color.red()), ui.spinRoiW->value());
}
}
else
{
if (view_points == true)
{
for (int n = 0; n < select_xy.size(); n++)
{
cv::line(dstImage, cv::Point(select_xy[n].x - cos(45 * M_PI / 180) * ui.spinCrossL->value(), select_xy[n].y - sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Point(select_xy[n].x + cos(45 * M_PI / 180) * ui.spinCrossL->value(), select_xy[n].y + sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Scalar(211, 0, 141), ui.spinRoiW->value());
cv::line(dstImage, cv::Point(select_xy[n].x - cos(45 * M_PI / 180) * ui.spinCrossL->value(), select_xy[n].y + sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Point(select_xy[n].x + cos(45 * M_PI / 180) * ui.spinCrossL->value(), select_xy[n].y - sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Scalar(211, 0, 141), ui.spinRoiW->value());
}
for (int n = 0; n < cull_xy.size(); n++)
{
cv::line(dstImage, cv::Point(cull_xy[n].x - cos(45 * M_PI / 180) * ui.spinCrossL->value(), cull_xy[n].y - sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Point(cull_xy[n].x + cos(45 * M_PI / 180) * ui.spinCrossL->value(), cull_xy[n].y + sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Scalar(0, 0, 255), ui.spinRoiW->value());
cv::line(dstImage, cv::Point(cull_xy[n].x - cos(45 * M_PI / 180) * ui.spinCrossL->value(), cull_xy[n].y + sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Point(cull_xy[n].x + cos(45 * M_PI / 180) * ui.spinCrossL->value(), cull_xy[n].y - sin(45 * M_PI / 180) * ui.spinCrossL->value()), cv::Scalar(0, 0, 255), ui.spinRoiW->value());
}
}
GetToolBase()->m_Tools[tool_index].PublicImage.Name = "图像";
}
GetToolBase()->m_Tools[tool_index].PublicImage.OutputImage = dstImage;
GetToolBase()->m_Tools[tool_index].PublicImage.OutputRoiImage = dstRoiImage;
GetToolBase()->m_Tools[tool_index].PublicGeometry.k = k;
GetToolBase()->m_Tools[tool_index].PublicGeometry.b = b;
GetToolBase()->m_Tools[tool_index].PublicResult.State = true;
return 0;
}
catch (...)
{
GetToolBase()->m_Tools[tool_index].PublicResult.State = false;
return -1;
}
}
int frmFindLine::ExecuteLink(const int int_link, const QString str_link, const QMap<QString, gVariable::Global_Var> variable_link)
{
try
{
gvariable.global_variable_link = variable_link;
if (int_link == 1)
{
strs.clear();
strs = str_link.split(".");
if (strs.size() == 1 || strs[1] != "图像")
{
QMessageBox msgBox(QMessageBox::Icon::NoIcon, "错误", "输入的链接错误!");
msgBox.setWindowIcon(QIcon(":/resource/error.png"));
msgBox.exec();
return -1;
}
ui.txtLinkImage->setText(str_link);
}
else if (int_link == 2)
{
strs.clear();
strs = str_link.split(".");
if (strs.size() == 1 || strs[1] != "匹配基准中心")
{
QMessageBox msgBox(QMessageBox::Icon::NoIcon, "错误", "输入的链接错误!");
msgBox.setWindowIcon(QIcon(":/resource/error.png"));
msgBox.exec();
return -1;
}
ui.txtLinkFollow->setText(str_link);
}
return 0;
}
catch (...)
{
return -1;
}
}
int frmFindLine::ExecuteAllLink(const QMap<QString, gVariable::Global_Var> g_variable_link)
{
try
{
gvariable.global_variable_link = g_variable_link;
return 0;
}
catch (...)
{
return -1;
}
}
int frmFindLine::InitSetToolData(const QVariant data)
{
try
{
InitFindLineData init_data;
init_data = data.value<InitFindLineData>();
if (init_data.use_roi == true)
{
view->ClearObj();
if (init_data.type == "caliper_p")
{
caliper_item = new Caliper(init_data.x1, init_data.y1, init_data.x2, init_data.y2, init_data.height);
caliper_item->caliper_init_state = true;
caliper_item->segment_line_num = init_data.segment_line_num;
view->AddItems(caliper_item);
caliper_item->line_small_points.clear();
caliper_item->line_big_points.clear();
for (int i = 0; i < init_data.line_s_points.size(); i++)
{
caliper_item->line_small_points.push_back(init_data.line_s_points[i]);
caliper_item->line_big_points.push_back(init_data.line_b_points[i]);
}
caliper_item->SetCaliper(init_data.pp1, init_data.pp2);
}
color = init_data.color;
//设置按钮背景颜色
QString style_color = "background-color: rgb(" + QString::number(color.red()) + "," + QString::number(color.green()) + "," + QString::number(color.blue()) + ")";
ui.btnRoiColor->setStyleSheet(style_color);
}
return 0;
}
catch (...)
{
return -1;
}
}
QVariant frmFindLine::InitGetToolData()
{
InitFindLineData init_data;
if (ui.checkUseROI->isChecked() == true)
{
init_data.use_roi = true;
if (ui.comboROIShape->currentIndex() == 0)
{
if (caliper_item->caliper_init_state == false)
{
return -1;
}
caliper_item->GetCaliper(caliper_p);
init_data.type = "caliper_p";
init_data.x1 = caliper_p.x1;
init_data.y1 = caliper_p.y1;
init_data.x2 = caliper_p.x2;
init_data.y2 = caliper_p.y2;
init_data.height = caliper_p.height;
init_data.row = caliper_p.row;
init_data.col = caliper_p.col;
init_data.len1 = caliper_p.len1;
init_data.len2 = caliper_p.len2;
init_data.angle = caliper_p.angle;
init_data.pp1 = caliper_p.pp1;
init_data.pp2 = caliper_p.pp2;
init_data.segment_line_num = caliper_item->segment_line_num;
init_data.color = color;
for (int i = 0; i < caliper_item->line_small_points.size(); i++)
{
init_data.line_s_points.append(caliper_item->line_small_points[i]);
init_data.line_b_points.append(caliper_item->line_big_points[i]);
}
}
}
else
{
init_data.use_roi = false;
}
return QVariant::fromValue(init_data);
}
void frmFindLine::on_btnExecute_clicked()
{
ui.btnExecute->setEnabled(false);
QApplication::processEvents();
view_points = true;
Execute(GetToolName());
ui.txtMsg->clear();
ui.txtMsg->append("-> 直线的斜率为:" + QString::number(k));
ui.txtMsg->append("-> 直线的截距为:" + QString::number(b));
QImage img(Mat2QImage(dstImage));
view->DispImage(img);
ui.btnExecute->setEnabled(true);
}
void frmFindLine::on_btnLinkImage_clicked()
{
QConfig::nFormState = 1;
}
void frmFindLine::on_btnDelLinkImage_clicked()
{
ui.txtLinkImage->clear();
}
void frmFindLine::on_btnLinkFollow_clicked()
{
QConfig::nFormState = 2;
}
void frmFindLine::on_btnDelLinkFollow_clicked()
{
ui.txtLinkFollow->clear();
}
void frmFindLine::on_btnAddROI_clicked()
{
view->ClearObj();
caliper_item = new Caliper(10, 160, 200, 160, 300);
caliper_item->caliper_init_state = true;
switch (ui.comboROIShape->currentIndex()) {
case 0:
caliper_item->segment_line_num = ui.spinSegment->value();
view->AddItems(caliper_item);
break;
}
}
void frmFindLine::on_btnDeleteROI_clicked()
{
caliper_item->caliper_init_state = false;
view->ClearObj();
}
void frmFindLine::on_btnRoiColor_clicked()
{
QColorDialog dlg(this);
dlg.setMinimumSize(547, 393);
dlg.setWindowTitle("Color Editor");
dlg.setCurrentColor(QColor(100, 111, 222));
dlg.setWindowIcon(QIcon(":/resource/color_edit.png"));
if (dlg.exec() == QColorDialog::Accepted)
{
color = dlg.selectedColor();
//设置按钮背景颜色
ui.btnRoiColor->setAutoFillBackground(true);
ui.btnRoiColor->setFlat(true);
QPalette palette = ui.btnRoiColor->palette();
palette.setColor(QPalette::Button, color);
ui.btnRoiColor->setPalette(palette);
}
}
void frmFindLine::on_spinSegment_valueChanged(int value)
{
caliper_item->segment_line_num = value;
}
//寻找边界点
//threshold_delta为阈值direction的值为0时代表“从白到黑”寻找边界点direction的值为1时代表“从黑到白”寻找边界点
//in_out_circle值为0时从内往外扫描值为1时从外往内扫描segment_num为分割线数量
int frmFindLine::FindBorderPoints(const cv::Mat& src_mat, const std::vector<QPointF> line_small_points, const std::vector<QPointF> line_big_points, std::vector<QPointF>& xy, const int threshold_delta, const int direction, const int in_out_circle, const int segment_num)
{
try
{
cv::Mat gray;
if (src_mat.channels() == 3)
{
cv::cvtColor(src_mat, gray, cv::COLOR_BGR2GRAY);
}
else if (src_mat.channels() == 4)
{
cv::cvtColor(src_mat, gray, cv::COLOR_RGBA2GRAY);
}
else
{
src_mat.copyTo(gray);
}
int ww = gray.cols;
int hh = gray.rows;
int bytes = ww * hh;
vector<unsigned char> rgbValues(bytes);
QPixmap pixmap = QPixmap::fromImage(Mat2QImage(gray));
QImage img = pixmap.toImage();
unsigned char* pData = img.bits();
int i, j;
for (i = 0; i < ww * hh * 4; i += 4)
{
rgbValues[i / 4] = pData[i];
}
vector<unsigned char> buffer8(bytes);
buffer8 = rgbValues;
//边界点
vector<QPointF> backPoint(segment_num);
vector<QPointF> backOutPoint(segment_num);
//寻找边界点
int m = 0;
//计算两点间的距离
double distance;
distance = pow((line_small_points[0].x() - line_big_points[0].x()), 2) + pow((line_small_points[0].y() - line_big_points[0].y()), 2);
distance = sqrt(distance);
//线图像上每一个点灰度颜色
QList<float> temparrclor = QList<float>();
temparrclor.reserve(5000);
//线图像上每一个点坐标
QList<QPointF> position = QList<QPointF>();
position.reserve(5000);
for (int k = 0; k < segment_num; k++)
{
temparrclor.clear();
position.clear();
float x_point;
float y_point;
if (in_out_circle == 0)
{
for (int n = 0; n < (int)distance; n++)
{
x_point = (n * (line_big_points[k].x() - line_small_points[k].x())) / distance + line_small_points[k].x();
y_point = (n * (line_big_points[k].y() - line_small_points[k].y())) / distance + line_small_points[k].y();
float tempf = abs(y_point - (int)y_point);
QPointF tempPt = QPointF(x_point, y_point);
float avgGrey = (float)buffer8[(int)y_point * ww + (int)x_point];
float avgGrey1 = (float)buffer8[(int)(y_point + 1) * ww + (int)x_point];
float grey = avgGrey * (1 - tempf) + avgGrey1 * tempf;
//插值灰度
temparrclor.push_back(grey);
position.push_back(tempPt);
}
}
else if (in_out_circle == 1)
{
for (int n = 0; n < (int)distance; n++)
{
x_point = (n * (line_small_points[k].x() - line_big_points[k].x())) / distance + line_big_points[k].x();
y_point = (n * (line_small_points[k].y() - line_big_points[k].y())) / distance + line_big_points[k].y();
float tempf = abs(y_point - (int)y_point);
QPointF tempPt = QPointF(x_point, y_point);
float avgGrey = (float)buffer8[(int)y_point * ww + (int)x_point];
float avgGrey1 = (float)buffer8[(int)(y_point + 1) * ww + (int)x_point];
float grey = avgGrey * (1 - tempf) + avgGrey1 * tempf;
//插值灰度
temparrclor.push_back(grey);
position.push_back(tempPt);
}
}
//找穿越点
QPointF return_point = FindCrosspointimprove(temparrclor, position, direction, threshold_delta);
if (return_point != QPointF(0, 0))
{
backPoint[m] = return_point;
m += 1;
}
}
backOutPoint.resize(m);
for (int n = 0; n < m; n++)
{
backOutPoint[n] = backPoint[n];
}
xy = backOutPoint;
return 0;
}
catch (...)
{
return -1;
}
}
//梯度和求穿越点
QPointF frmFindLine::FindCrosspointimprove(const QList<float>& lineTiDu, const QList<QPointF>& ijRecord, const int direction, const int threshold_delta)
{
try
{
//梯度和求穿越点,使用五个一组
QList<float> deltatemp = QList<float>();
deltatemp.reserve(5000);
deltatemp.clear();
QList<float> fenzuaverage = QList<float>();
fenzuaverage.reserve(5000);
fenzuaverage.clear();
for (int i = 0; i < lineTiDu.size() - 1; i++)
{
float grey1 = lineTiDu[i + 1];
float delta = (lineTiDu[i] - grey1);
if (abs(delta) < 5)
delta = 0;
deltatemp.push_back(delta);
}
int fenzuC = deltatemp.size() / 5;
for (int i = 0; i < fenzuC * 5; i += 5)
{
float sum5 = deltatemp[i] + deltatemp[i + 1] + deltatemp[i + 2] + deltatemp[i + 3] + deltatemp[i + 4];
float aver = sum5 / 5;
if (abs(aver) < 5)
aver = 0;
fenzuaverage.push_back(aver);
}
if (fenzuaverage.size() == 0) return QPointF();
int crosspoint = 0;
int crosspoint1 = 0;
//从白到黑寻找
if (direction == 0)
{
for (int iii = fenzuaverage.size() - 1; iii >= 0; iii--) //排除起点和终点
{
if (fenzuaverage[iii] > 0)
{
crosspoint = 5 * (iii);
break;
}
}
float maxVar = deltatemp[crosspoint];
for (int m = -5; m < 5; m++)
{
int tempint = crosspoint + m;
if (crosspoint == 0)
tempint = 0;
if (deltatemp[tempint] >= maxVar)
{
maxVar = deltatemp[tempint];
crosspoint1 = tempint;
}
}
}
//从黑到白寻找
else if (direction == 1)
{
for (int iii = 0; iii <= fenzuaverage.size() - 1; iii++) //排除起点和终点
{
if (fenzuaverage[iii] < 0)
{
crosspoint = 5 * (iii);
break;
}
}
float minVar = deltatemp[crosspoint];
for (int m = -5; m < 5; m++)
{
int tempint = crosspoint + m;
if (crosspoint == 0)
tempint = 0;
if (deltatemp[tempint] <= minVar)
{
minVar = deltatemp[tempint];
crosspoint1 = tempint;
}
}
}
//阈值判别
if (fenzuaverage[crosspoint / 5] * 5 >= threshold_delta || fenzuaverage[crosspoint / 5] * 5 <= -threshold_delta)
{
//穿越点的index对应坐标(crosspoint1为线图像中穿越点index)
return ijRecord[crosspoint1];
}
else
{
return QPointF(0, 0); //没有穿越点返回0,0
}
}
catch (...)
{
return QPointF(0, 0); //没有穿越点返回0,0
}
}
//计算点到直线的距离(P为线外一点AB为线段两个端点)
double frmFindLine::GetDistP2L(const cv::Point2f pointP, const cv::Point2f pointA, const cv::Point2f pointB)
{
//求直线方程
double A = 0, B = 0, C = 0;
A = pointA.y - pointB.y;
B = pointB.x - pointA.x;
C = pointA.x * pointB.y - pointA.y * pointB.x;
double distance = 0;
distance = ((double)abs(A * pointP.x + B * pointP.y + C)) / ((double)sqrtf(A * A + B * B));
return distance;
}
cv::Point2f frmFindLine::AffineTransformPoint(const cv::Point2f match_origin_point, const double match_origin_angle, const cv::Point2f match_current_point, const double match_current_angle, const cv::Point2f input_point)
{
try
{
//获取旋转矩阵
cv::Mat rotMat = cv::getRotationMatrix2D(match_origin_point, (match_current_angle - match_origin_angle), 1.0);
//转换成3*3矩阵
cv::Mat rotMat2 = cv::Mat::zeros(3, 3, CV_32FC1);
rotMat2.at<float>(0, 0) = (float)rotMat.at<double>(0, 0);
rotMat2.at<float>(0, 1) = (float)rotMat.at<double>(0, 1);
rotMat2.at<float>(0, 2) = (float)rotMat.at<double>(0, 2);
rotMat2.at<float>(1, 0) = (float)rotMat.at<double>(1, 0);
rotMat2.at<float>(1, 1) = (float)rotMat.at<double>(1, 1);
rotMat2.at<float>(1, 2) = (float)rotMat.at<double>(1, 2);
rotMat2.at<float>(2, 2) = 1;
//平移矩阵
cv::Mat t_mat = cv::Mat::zeros(3, 3, CV_32FC1);
t_mat.at<float>(0, 0) = 1;
t_mat.at<float>(0, 2) = match_current_point.x - match_origin_point.x;
t_mat.at<float>(1, 1) = 1;
t_mat.at<float>(1, 2) = match_current_point.y - match_origin_point.y;
t_mat.at<float>(2, 2) = 1;
//平移矩阵*旋转矩阵,得到仿射变换阵
cv::Mat resMat = t_mat * rotMat2;
double a11 = (double)resMat.at<float>(0, 0);
double a12 = (double)resMat.at<float>(0, 1);
double a13 = (double)resMat.at<float>(0, 2);
double a21 = (double)resMat.at<float>(1, 0);
double a22 = (double)resMat.at<float>(1, 1);
double a23 = (double)resMat.at<float>(1, 2);
cv::Point2f out_point;
out_point = cv::Point2f((input_point.x * a11 + input_point.y * a12 + a13), (input_point.x * a21 + input_point.y * a22 + a23));
return out_point;
}
catch (...)
{
return cv::Point2f(0, 0);
}
}
QImage frmFindLine::Mat2QImage(const cv::Mat& mat)
{
if (mat.empty())
{
return QImage();
}
if (mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
image.setColorCount(256);
for (int i = 0; i < 256; i++)
{
image.setColor(i, qRgb(i, i, i));
}
uchar* pSrc = mat.data;
for (int row = 0; row < mat.rows; row++)
{
uchar* pDest = image.scanLine(row);
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
return image;
}
else if (mat.type() == CV_8UC3)
{
const uchar* pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
else if (mat.type() == CV_8UC4)
{
const uchar* pSrc = (const uchar*)mat.data;
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);
return image.copy();
}
else
{
return QImage();
}
}
//全局变量控制
int QConfig::nFormState = 0;