1 Star 0 Fork 8

mx_foreverGod / VideoAnnotator

forked from ctguhzy / VideoAnnotator 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
VideoView.cxx 17.71 KB
一键复制 编辑 原始数据 按行查看 历史
ctguhzy 提交于 2021-03-21 21:21 . Update file rights.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
#include <QPainter>
#include <QSettings>
#include "VideoView.hxx"
#include "Sequence.hxx"
#include "FramePool.hxx"
#include "VideoThread.hxx"
#include "VideoController.hxx"
#include "TrackedObject.hxx"
#include "Project.hxx"
#include "MainWindow.hxx"
int cursorDist = 10;
//extern QSettings* __globalSettings;
VideoView::VideoView(QWidget *parent):QWidget(0)
{
_imageData = 0;
_timer = new QTimer();
_timer->setInterval(15);
connect(_timer,SIGNAL(timeout()),this,SLOT(updateFrame()));
_timer->start();
_dragingRect = false;
_status = VW_STATUS_DISPLAYING;
setMouseTracking(true);
setMinimumHeight(400);
setMinimumWidth(600);
}
void VideoView::paintEvent(QPaintEvent *event)
{
if (!_imageData)
return;
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return;
QImage image(_imageData + sizeof(VideoFrameInfo), sequence->getVideoWidth(), sequence->getVideoHeight(),QImage::Format_RGB888);
QRect rect = QRect(0, 0, geometry().width(), geometry().height());
QPainter painter(this);
painter.drawImage(rect, image.rgbSwapped(), QRect(0,0,image.width(),image.height()));
drawNewObject(painter);
drawTrackingObject(painter);
drawTrackedObject(painter);
drawTextInfo(painter);
painter.end();
}
void VideoView::updateFrame()
{
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return;
if( !_imageData )
{
int imgWidth = sequence->getVideoWidth();
int imgHeight = sequence->getVideoHeight();
if( imgWidth < 1 || imgHeight < 1 )
return;
FramePool* pool = sequence->getFramePool();
_imageData = (uchar*)malloc(pool->getPageSize());
return;
}
if (sequence->getTrackedFramePool()->popFrame((char*)_imageData))
{
VideoFrameInfo* vfi = (VideoFrameInfo*)_imageData;
_frameIndex = vfi->FrameIndex;
sequence->setCurrentFrameIndex(_frameIndex);
sequence->setCurrentTimestamp(vfi->TimeStamp);
update();
emit frameInfoUpdated();
}
}
void VideoView::mousePressEvent(QMouseEvent *event)
{
if (_status == VW_STATUS_DISPLAYING)
{
if (event->buttons() & Qt::LeftButton)
{
_startPoint = event->pos();
_endPoint = _startPoint;
_dragingRect = true;
}
}
else if (_status = VW_STATUS_EDITING)
{
Qt::CursorShape shape = cursor().shape();
if (shape == Qt::SizeAllCursor)
{
_startPoint = event->pos();
_endPoint = _startPoint;
}
else if (shape == Qt::SizeHorCursor)
{
_startPoint = event->pos();
_endPoint = _startPoint;
}
else if (shape == Qt::SizeVerCursor)
{
_startPoint = event->pos();
_endPoint = _startPoint;
}
}
}
void VideoView::mouseMoveEvent(QMouseEvent *event)
{
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return;
if (_status == VW_STATUS_DISPLAYING)
{
if (event->buttons() & Qt::LeftButton)
{
if (_dragingRect)
{
_endPoint = event->pos();
update();
}
}
}
else if (_status == VW_STATUS_EDITING)
{
if (event->buttons() == Qt::NoButton)
{
QPoint mpt = event->pos();
std::vector<TrackedObject*>* objects = sequence->getTrackedObjects();
bool horizentalCursor = false;
bool verticalCursor = false;
//// North East cursor
//bool neCursor = false;
//// North West cursor
//bool nwCursor = false;
// Moving cursor
bool mvCursor = false;
for (int i = 0; i < objects->size(); i++)
{
TrackedObject* tobj = objects->at(i);
if (tobj->isSelected())
{
cv::Rect2d crect = tobj->getRect(_frameIndex);
QRect qrect = cvRect2QRect(crect);
if (((abs(qrect.x() - mpt.x()) < cursorDist) || (abs(qrect.x() + qrect.width() - mpt.x()) < cursorDist))
&& ((mpt.y() - qrect.y() > cursorDist) && (qrect.y() + qrect.height() - cursorDist > mpt.y())))
horizentalCursor = true;
else if (((abs(qrect.y() - mpt.y()) < cursorDist) || (abs(qrect.y() + qrect.height() - mpt.y()) < cursorDist))
&& ((mpt.x() - qrect.x() > cursorDist) && (qrect.x() + qrect.width() - cursorDist > mpt.x())))
verticalCursor = true;
else if ((mpt.x() > qrect.x() + cursorDist) &&
(qrect.x() + qrect.width() - cursorDist > mpt.x()) &&
(mpt.y() > qrect.y() + cursorDist) &&
(qrect.y() + qrect.height() - cursorDist > mpt.y()))
mvCursor = true;
}
}
if (horizentalCursor)
setCursor(QCursor(Qt::SizeHorCursor));
else if (verticalCursor)
setCursor(QCursor(Qt::SizeVerCursor));
else if (mvCursor)
setCursor(QCursor(Qt::SizeAllCursor));
else
setCursor(QCursor(Qt::ArrowCursor));
}
else if( event->buttons() & Qt::LeftButton )
{
Qt::CursorShape shape = cursor().shape();
if (shape == Qt::SizeAllCursor)
{
_endPoint = event->pos();
}
else if (shape == Qt::SizeHorCursor)
{
_endPoint = event->pos();
}
else if (shape == Qt::SizeVerCursor)
{
_endPoint = event->pos();
}
update();
}
}
}
void VideoView::mouseReleaseEvent(QMouseEvent *event)
{
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return;
if (_status == VW_STATUS_DISPLAYING)
{
if (_dragingRect)
{
_endPoint = event->pos();
if( abs(_startPoint.x() - _endPoint.x()) > 20 && abs( _startPoint.y() - _endPoint.y()) > 20 )
_rects.push_back(QRect(_startPoint, _endPoint));
_dragingRect = false;
if (_rects.size() > 0)
emit rectSelected();
}
}
else if( _status == VW_STATUS_EDITING )
{
_endPoint = event->pos();
if (event->button() == Qt::LeftButton)
{
TrackedObject* tobj = nullptr;
std::vector<TrackedObject*>* objects = sequence->getTrackedObjects();
for (int i = 0; i < objects->size(); i++)
{
tobj = objects->at(i);
if (tobj->isSelected())
break;
}
if (tobj == nullptr)
return;
Qt::CursorShape shape = cursor().shape();
if (shape == Qt::SizeAllCursor)
{
cv::Rect2d rect = tobj->getRect(_frameIndex);
QPoint pt = _endPoint - _startPoint;
cv::Point2d cpt = qPoint2cvPoint(pt);
rect.x += cpt.x;
rect.y += cpt.y;
tobj->pushRect(_frameIndex, rect);
_startPoint = _endPoint;
}
else if (shape == Qt::SizeHorCursor)
{
cv::Rect2d crect = tobj->getRect(_frameIndex);
QRect qrect = cvRect2QRect(crect);
QPoint pt = _endPoint - _startPoint;
cv::Point2d cpt = qPoint2cvPoint(pt);
QRect trect;
if (abs(_startPoint.x() - qrect.x()) <= cursorDist)
{
trect.setX(qrect.x() + pt.x());
trect.setY(qrect.y());
trect.setWidth(qrect.width() - pt.x());
trect.setHeight(qrect.height());
}
else
{
trect.setX(qrect.x());
trect.setY(qrect.y());
trect.setWidth(qrect.width() + pt.x());
trect.setHeight(qrect.height());
}
cv::Rect2d nrect = qRect2cvRect(trect);
tobj->pushRect(_frameIndex, nrect);
_startPoint = _endPoint;
}
else if (shape == Qt::SizeVerCursor)
{
cv::Rect2d crect = tobj->getRect(_frameIndex);
QRect qrect = cvRect2QRect(crect);
QPoint pt = _endPoint - _startPoint;
cv::Point2d cpt = qPoint2cvPoint(pt);
QRect trect;
if (abs(_startPoint.y() - qrect.y()) <= cursorDist)
{
trect.setX(qrect.x());
trect.setY(qrect.y() + pt.y());
trect.setWidth(qrect.width());
trect.setHeight(qrect.height() - pt.y());
}
else
{
trect.setX(qrect.x());
trect.setY(qrect.y());
trect.setWidth(qrect.width());
trect.setHeight(qrect.height() + pt.y());
}
cv::Rect2d nrect = qRect2cvRect(trect);
tobj->pushRect(_frameIndex, nrect);
_startPoint = _endPoint;
}
update();
}
}
}
QRect VideoView::cvRect2QRect(cv::Rect2d rect)
{
QRect geoRect = geometry();
QRect result;
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return result;
result.setX(rect.x / sequence->getVideoWidth() * geoRect.width());
result.setY(rect.y / sequence->getVideoHeight() * geoRect.height());
result.setWidth(rect.width / sequence->getVideoWidth() * geoRect.width());
result.setHeight(rect.height / sequence->getVideoHeight() * geoRect.height());
return result;
}
cv::Rect2d VideoView::qRect2cvRect(QRect rect)
{
QRect geoRect = geometry();
cv::Rect2d result;
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return result;
result.x = rect.x() * 1.0 / geoRect.width() * sequence->getVideoWidth();
result.y = rect.y() * 1.0 / geoRect.height() * sequence->getVideoHeight();
result.width = rect.width() * 1.0 / geoRect.width() * sequence->getVideoWidth();
result.height = rect.height() * 1.0 / geoRect.height() * sequence->getVideoHeight();
if (result.width < 0.0)
{
result.x += result.width;
result.width = -result.width;
}
if (result.height < 0.0)
{
result.y += result.height;
result.height = -result.height;
}
return result;
}
cv::Point2d VideoView::qPoint2cvPoint(QPoint qpt)
{
cv::Point2d pt;
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return pt;
pt.x = qpt.x() * 1.0 / width() * sequence->getVideoWidth();
pt.y = qpt.y() * 1.0 / height() * sequence->getVideoHeight();
return pt;
}
QPoint VideoView::cvPoint2QPoint(cv::Point2d cpt)
{
QPoint pt;
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return pt;
pt.setX(cpt.x / sequence->getVideoWidth() * width());
pt.setY(cpt.y / sequence->getVideoHeight() * height());
return pt;
}
std::vector<cv::Rect2d> VideoView::getCvRects()
{
std::vector<cv::Rect2d> results;
for (int i = 0; i < _rects.size(); i++)
{
results.push_back(qRect2cvRect(_rects.at(i)));
}
return results;
}
void VideoView::drawNewObject(QPainter& painter)
{
QPen pen;
pen.setStyle(Qt::SolidLine);
pen.setWidth(3);
pen.setColor(QColor(255, 255, 0, 127));
painter.setPen(pen);
if (_dragingRect)
{
painter.drawRect(QRect(_startPoint, _endPoint));
}
for (int i = 0; i < _rects.size(); i++)
{
painter.drawRect(_rects.at(i));
}
}
void VideoView::drawTrackingObject(QPainter& painter)
{
//Draw Tracking Box
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return;
std::vector<TrackedObject*>* objects = sequence->getTrackingObjects();
QPen pen;
pen.setStyle(Qt::SolidLine);
pen.setWidth(3);
pen.setColor(QColor(255, 0, 0, 127));
painter.setPen(pen);
for (int i = 0; i < objects->size(); i++)
{
TrackedObject* tobj = objects->at(i);
cv::Rect2d crect = tobj->getRect(_frameIndex);
QRect rect = cvRect2QRect(crect);
painter.drawRect(rect);
}
}
void VideoView::drawTrackedObject(QPainter& painter)
{
//Draw Tracking Box
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return;
std::vector<TrackedObject*>* objects = sequence->getTrackedObjects();
QPen pen;
pen.setStyle(Qt::SolidLine);
pen.setWidth(3);
pen.setColor(QColor(0, 0, 255, 127));
painter.setPen(pen);
bool noSelectedObjectToDraw = true;
for (int i = 0; i < objects->size(); i++)
{
TrackedObject* tobj = objects->at(i);
if (!tobj->isVisible()) continue;
cv::Rect2d crect = tobj->getRect(_frameIndex);
if (crect.x == 0.0 && crect.y == 0.0 && crect.width == 0.0 && crect.height == 0.0)
continue;
int classIndex = tobj->getClassIndex();
std::vector<Class*>* classes = _project->getClasses();
QString objectClassName = QString("Object");
for (int j = 0; j < classes->size(); j++)
{
Class* cls = classes->at(j);
if (cls->getId() == classIndex)
{
objectClassName = cls->getName().c_str();
break;
}
}
noSelectedObjectToDraw = false;
QRect rect = cvRect2QRect(crect);
QFont font("Times", 12);
font.setBold(true);
QFontMetrics fm(font);
QString textString = QString("%1:%2").arg(objectClassName).arg(tobj->getObjectId());
int textWidthInPixels = fm.width(textString);
int textHeightInPixels = fm.height();
painter.setFont(font);
QRect textRect;
textRect.setX(rect.x());
textRect.setY(rect.y() - textHeightInPixels - 10 );
textRect.setHeight(textHeightInPixels + 10 );
textRect.setWidth(textWidthInPixels + 10 );
painter.setBrush(Qt::SolidPattern);
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(0, 0, 255, 127));
painter.drawRect(textRect);
painter.setPen(QColor(255, 255, 0, 255));
painter.drawText(textRect.x()+5, rect.y() - 5, textString);
painter.setBrush(Qt::NoBrush);
painter.setPen(pen);
painter.drawRect(rect);
if (tobj->isSelected())
{
drawSelectedObject(painter, rect);
}
}
if (noSelectedObjectToDraw)
{
_status = VW_STATUS_DISPLAYING;
sequence->desectAllTrackedObjects();
}
}
void VideoView::drawSelectedObject(QPainter& painter, QRect& rect)
{
int rectWidth = 9;
// rect 0
QRect drect;
drect.setX(rect.x() - rectWidth / 2);
drect.setY(rect.y() - rectWidth / 2);
drect.setWidth(rectWidth);
drect.setHeight(rectWidth);
painter.drawRect(drect);
// rect 1
drect.setX(rect.x() + rect.width() / 2 - rectWidth / 2);
drect.setY(rect.y() - rectWidth / 2);
drect.setWidth(rectWidth);
drect.setHeight(rectWidth);
painter.drawRect(drect);
// rect 2
drect.setX(rect.x() + rect.width() - rectWidth / 2);
drect.setY(rect.y() - rectWidth / 2);
drect.setWidth(rectWidth);
drect.setHeight(rectWidth);
painter.drawRect(drect);
// rect 3
drect.setX(rect.x() - rectWidth / 2);
drect.setY(rect.y() + rect.height() / 2 - rectWidth / 2);
drect.setWidth(rectWidth);
drect.setHeight(rectWidth);
painter.drawRect(drect);
// rect 4
//drect.setX(rect.x() + rect.width() / 2 - rectWidth / 2);
//drect.setY(rect.y() + rect.height() / 2 - rectWidth / 2);
//drect.setWidth(rectWidth);
//drect.setHeight(rectWidth);
//painter.drawRect(drect);
// rect 5
drect.setX(rect.x() + rect.width() - rectWidth / 2);
drect.setY(rect.y() + rect.height() / 2 - rectWidth / 2);
drect.setWidth(rectWidth);
drect.setHeight(rectWidth);
painter.drawRect(drect);
// rect 6
drect.setX(rect.x() - rectWidth / 2);
drect.setY(rect.y() + rect.height() - rectWidth / 2);
drect.setWidth(rectWidth);
drect.setHeight(rectWidth);
painter.drawRect(drect);
// rect 7
drect.setX(rect.x() + rect.width() / 2 - rectWidth / 2);
drect.setY(rect.y() + rect.height() - rectWidth / 2);
drect.setWidth(rectWidth);
drect.setHeight(rectWidth);
painter.drawRect(drect);
// rect 8
drect.setX(rect.x() + rect.width() - rectWidth / 2);
drect.setY(rect.y() + rect.height() - rectWidth / 2);
drect.setWidth(rectWidth);
drect.setHeight(rectWidth);
painter.drawRect(drect);
// draw editing rect
Qt::CursorShape shape = cursor().shape();
if (shape == Qt::SizeAllCursor)
{
QRect trect;
trect.setX(rect.x() + (_endPoint.x() - _startPoint.x()));
trect.setY(rect.y() + (_endPoint.y() - _startPoint.y()));
trect.setWidth(rect.width());
trect.setHeight(rect.height());
painter.drawRect(trect);
}
else if (shape == Qt::SizeHorCursor)
{
int tx = _endPoint.x() - _startPoint.x();
QRect trect;
if (abs(_startPoint.x() - rect.x()) <= cursorDist)
{
trect.setX(rect.x() + tx);
trect.setY(rect.y());
trect.setWidth(rect.width() - tx);
trect.setHeight(rect.height());
}
else
{
trect.setX(rect.x());
trect.setY(rect.y());
trect.setWidth(rect.width() + tx);
trect.setHeight(rect.height());
}
painter.drawRect(trect);
}
else if (shape == Qt::SizeVerCursor)
{
int ty = _endPoint.y() - _startPoint.y();
QRect trect;
if (abs(_startPoint.y() - rect.y()) <= cursorDist)
{
trect.setX(rect.x());
trect.setY(rect.y() + ty);
trect.setWidth(rect.width());
trect.setHeight(rect.height() - ty);
}
else
{
trect.setX(rect.x());
trect.setY(rect.y());
trect.setWidth(rect.width());
trect.setHeight(rect.height() + ty);
}
painter.drawRect(trect);
}
}
void VideoView::drawTextInfo(QPainter &painter)
{
QFont font("Times", 18);
font.setBold(true);
QFontMetrics fm(font);
QString textString = QString("Frame:%1").arg(_frameIndex);
int textWidthInPixels = fm.width(textString);
int textHeightInPixels = fm.height();
painter.setFont(font);
QRect canvas = geometry();
QPoint pt;
pt.setX(canvas.width() - textWidthInPixels);
pt.setY(textHeightInPixels);
QRect rect(pt.x(), pt.y() - textHeightInPixels + 5, textWidthInPixels, textHeightInPixels);
painter.setBrush(Qt::black);
painter.setPen(Qt::black);
painter.drawRect(rect);
painter.setBrush(Qt::red);
painter.setPen(Qt::red);
painter.drawText(pt, textString);
}
void VideoView::mouseDoubleClickEvent(QMouseEvent *event)
{
if (!_controller->isPaused())
return;
Sequence* sequence = _project->getActiveSequence();
if (!sequence) return;
QPoint pt = event->pos();
cv::Point2d cpt = qPoint2cvPoint(pt);
std::vector<TrackedObject*>* objects = sequence->getTrackedObjects();
bool rectSelectedFlag = false;
for (int i = 0; i < objects->size(); i++)
{
TrackedObject* obj = objects->at(i);
cv::Rect2d orect = obj->getRect(_frameIndex);
if ((cpt.x <= orect.x + orect.width) &&
(cpt.x >= orect.x) &&
(cpt.y <= orect.y + orect.height) &&
(cpt.y >= orect.y))
{
obj->select();
rectSelectedFlag = true;
}
else
{
obj->deselect();
}
}
if (rectSelectedFlag)
{
_status = VW_STATUS_EDITING;
clearRects();
emit objectSelected();
}
else
{
_status = VW_STATUS_DISPLAYING;
emit objectUnSelected();
}
update();
}
void VideoView::reset()
{
if (_imageData)
{
free(_imageData);
_imageData = 0;
}
}
C++
1
https://gitee.com/Do_yourself_maxin/VideoAnnotator.git
git@gitee.com:Do_yourself_maxin/VideoAnnotator.git
Do_yourself_maxin
VideoAnnotator
VideoAnnotator
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891