Esempio n. 1
0
/**
 Draw the robot position in the original image sequence.
 Need to know the entire camera calibration (and more) for this...
 **/
QImage showRobotTrackUndistorted( IplImage*           img,        ///< original avi image
                                  const RobotTracker* tracker,    ///< robot tracker
                                  int                 flip        ///< flip output coords?
                                )
{
    // Convert from IplImage to QImage...
    const QSize imgSize( img->width,img->height );
    QImage qimage = QImage( imgSize, QImage::Format_RGB888 );

    CvMat mtxWrapper;
    cvInitMatHeader( &mtxWrapper,
                     img->height,
                     img->width,
                     CV_8UC3,
                     qimage.bits() );

    cvConvertImage( img, &mtxWrapper, flip );

    // Now draw on top of the QImage...

    QPainter painter(&qimage);
    painter.setRenderHint(QPainter::Antialiasing, true);

    QPen penRed( QColor(255,0,0) );
    QPen penBlue( QColor(0,0,255) );
    QPen penRedGreen( QColor(255,255,0) );

    CvPoint2D32f offset = *tracker->GetOffsetParams();
    const CameraCalibration* cal = tracker->GetCalibration();

    // Draw the path taken so far (but each point needs to be converted from plane, to image co-ordinates)
    const TrackHistory& history = tracker->GetHistory();

    if ( history.size() > 1 )
    {
        CvPoint2D32f pos = history[0].GetPosition();
        pos.x += offset.x;
        pos.y += offset.y;
        CvPoint2D32f oldPosf = cal->PlaneToImage( pos );

        if ( flip )
        {
            oldPosf.y = img->height - oldPosf.y;
        }

        CvPoint oldPos = cvPoint( ( int )oldPosf.x, ( int )oldPosf.y );

        for ( unsigned int i = 1; i < history.size(); ++i )
        {
            double tdiff = fabs( history[i].t() - history[i - 1].t() );

            if ( tdiff > 2000.0 / 3.0 )
            {
                pos = history[i].GetPosition();
                pos.x += offset.x;
                pos.y += offset.y;
                oldPosf = cal->PlaneToImage( pos );

                if ( flip )
                {
                    oldPosf.y = img->height - oldPosf.y;
                }

                oldPos = cvPoint( ( int )oldPosf.x, ( int )oldPosf.y );
            }
            else
            {
                pos = history[i].GetPosition();
                pos.x += offset.x;
                pos.y += offset.y;
                CvPoint2D32f newPosf = cal->PlaneToImage( pos );

                if ( flip )
                {
                    newPosf.y = img->height - newPosf.y;
                }

                CvPoint newPos = cvPoint( ( int )newPosf.x, ( int )newPosf.y );

                //CvScalar colour;

                //float err = expf( -powf( (1.f-history[i].GetError())/0.5f, 4) );
                //float col = 255*err;
                //colour = CV_RGB( 255,0,0 ); //cvScalar( col, col, 255 );
                //  if ( err > 0.35f )
                //  {
                //      colour = cvScalar(0,255,0);
                //  }
                //  else
                //  {
                //      colour = cvScalar(0,0,255);
                //  }

                //cvLine( img, oldPos, newPos, colour, 1, CV_AA );

                penRed.setWidth( 2 );
                painter.setPen( penRed );
                painter.drawLine( oldPos.x, oldPos.y, newPos.x, newPos.y );
                oldPos = newPos;
            }
        }
    }

    return qimage;
}
Esempio n. 2
0
bool SingleVarStats::OperateModelGraphic(CMdlGraphicWnd &Wnd, CMdlGraphic &Grf)
{
	const COLORREF White = COLORREF(RGB(255,255,255));
	const COLORREF Black = COLORREF(RGB(0,0,0));
	const COLORREF Blue  = COLORREF(RGB(0,0,255));
	const COLORREF Cyan  = COLORREF(RGB(0,255,255));
	const COLORREF Red   = COLORREF(RGB(255,0,0));
	const COLORREF Green = COLORREF(RGB(0,255,0));
	switch (Wnd.m_eTask)
	{
	case MGT_Create:
		Wnd.m_pWnd->SetWindowPos(NULL, 0, 0, 200, 200, SWP_NOMOVE | SWP_NOZORDER);
		break;
	case MGT_Size:
		Wnd.m_pWnd->Invalidate();
		break;
	case MGT_Move:
		break;
	case MGT_EraseBkgnd:
		Wnd.m_bReturn = 0;
		break;
	case MGT_Paint:
		Wnd.m_pPaintDC->FillSolidRect(Wnd.m_ClientRect, Black);
		Wnd.m_pPaintDC->SetTextColor(Green);
		CPen penWhite(PS_SOLID, 0, White);
		CPen penGreen(PS_SOLID, 0, Green);
		CPen penRed(PS_SOLID, 0, Red);
		CBrush brushRed(Red);
		int nTextSize = Wnd.m_TextSize.y;
		int nBorderSpace = nTextSize;
		int nTextSpace = 4;
		int nAxesSpace = 4;
#if (_MSC_VER >= 1400)
		int nTopSpace = nBorderSpace + nTextSize;
		int nAxesLeft = nBorderSpace + nTextSize + nTextSpace + nAxesSpace;
#else
		int nTopSpace = nBorderSpace + nTextSize + nAxesSpace;
		int nAxesLeft = nBorderSpace + nAxesSpace;
#endif
		int nCheckSize = nAxesSpace - 1;
		int minSpace = 10;
		//Draw axes:
		int nAxesTop = nTopSpace,
			nAxesBottom = Wnd.m_ClientRect.bottom - (nBorderSpace + 2 * nTextSize + nTextSpace + nAxesSpace),
			nAxesRight = Wnd.m_ClientRect.right - (nBorderSpace);
		if (nAxesBottom - nAxesTop <= 0 || nAxesRight - nAxesLeft <= 0)
			break;
		POINT axes[] = { 
			{nAxesLeft, nAxesTop},
			{nAxesLeft, nAxesBottom},
			{nAxesRight, nAxesBottom} };
		CPen* oldPen = Wnd.m_pPaintDC->SelectObject(&penGreen);
		Wnd.m_pPaintDC->Polyline(axes, 3);
		int nArrowSize = 3;
		POINT ArrowTop[] = {
			{nAxesLeft, nAxesTop - nArrowSize},
			{nAxesLeft - nArrowSize, nAxesTop},
			{nAxesLeft + nArrowSize, nAxesTop},
			{nAxesLeft, nAxesTop - nArrowSize} };
		POINT ArrowSide[] = {
			{nAxesRight + nArrowSize, nAxesBottom},
			{nAxesRight, nAxesBottom - nArrowSize},
			{nAxesRight, nAxesBottom + nArrowSize},
			{nAxesRight + nArrowSize, nAxesBottom} };
		Wnd.m_pPaintDC->Polygon(ArrowTop, 4);
		Wnd.m_pPaintDC->Polygon(ArrowSide, 4);

		//Draw blocks, and % values above blocks.
		float blockWidth = (float)(nAxesRight - nAxesLeft) / (lHistoCount + 2);
		int MaxCount = 0;
		for (int i = 0; i < lHistoCount + 2; i++)
			if (pHistoBucketCounts[i] > MaxCount) MaxCount = pHistoBucketCounts[i];
		int FullScale = (int)(MaxCount * 1.1);
		if (FullScale < 1) FullScale = 1; //Avoid divide by zero errors.
		int nAxesHeight = nAxesBottom - nAxesTop;
		if (MaxCount > 0)
		{
			Wnd.m_pPaintDC->SelectObject(&penRed);
			CBrush* oldBrush = Wnd.m_pPaintDC->SelectObject(&brushRed);

			Wnd.m_pPaintDC->SetTextAlign(TA_BOTTOM | TA_CENTER);

			for (int i = 0; i < lHistoCount + 2; i++)
			{
				if (i == 1)	{
					Wnd.m_pPaintDC->SelectObject(&penWhite);
					Wnd.m_pPaintDC->SelectObject(oldBrush);
				}
				if (i == lHistoCount + 1) {
					Wnd.m_pPaintDC->SelectObject(&penRed);
					Wnd.m_pPaintDC->SelectObject(&brushRed);
				}
				Wnd.m_pPaintDC->Rectangle(
					nAxesLeft + (int)(i*blockWidth),		nAxesBottom - (nAxesHeight * pHistoBucketCounts[i]) / FullScale, 
					nAxesLeft + (int)((i+1)*blockWidth),	nAxesBottom);

				if (lRecordsSinceHistoReset > 0)
				{
					double d = 100.0 * pHistoBucketCounts[i] / lRecordsSinceHistoReset;
					int perc = d - (int)d < 0.5 ? (int) d : (int) d + 1;
					CString percent; percent.Format("%i%%", perc);
					Wnd.m_pPaintDC->TextOut(nAxesLeft + (int)((i + 0.5)*blockWidth), nAxesBottom - (nAxesHeight * pHistoBucketCounts[i]) / FullScale - 1, percent);
				}
			}
			
			Wnd.m_pPaintDC->SelectObject(&penWhite);
			Wnd.m_pPaintDC->SelectObject(oldBrush);
		}

		//Draw checks and axis values:
		double offset = 0, scale = 1;
		if (TagCnvFamily[nTagCnvUsed].Valid())
		{
			offset = TagCnvFamily[nTagCnvUsed].Offset();
			scale = TagCnvFamily[nTagCnvUsed].Scale();
		}

		Wnd.m_pPaintDC->SetTextAlign(TA_TOP | TA_CENTER);
		Wnd.m_pPaintDC->SelectObject(&penGreen);
		int lastLabel = 0;
		for (int i = 1; i < lHistoCount + 2; i++)
		{
			POINT Checkline[] = {
				{nAxesLeft + (int)(i * blockWidth), nAxesBottom},
				{nAxesLeft + (int)(i * blockWidth), nAxesBottom + nCheckSize}};
			Wnd.m_pPaintDC->Polyline(Checkline, 2);
			
			CString value;
			if (pHistoBucketBorders[i] < 100) //Because the %.2g formatting doesn't work like it should
				value.Format("%.2g", pHistoBucketBorders[i] * scale + offset);
			else if (pHistoBucketBorders[i] < 1E4)
				value.Format("%.0f", pHistoBucketBorders[i] * scale + offset);
			else
				value.Format("%.1e", pHistoBucketBorders[i] * scale + offset);

			if (nAxesLeft + (int)(i * blockWidth) - lastLabel > Wnd.m_pPaintDC->GetTextExtent(value).cx / 2 + minSpace)
			{
				Wnd.m_pPaintDC->TextOut(nAxesLeft + (int)(i * blockWidth), nAxesBottom + nAxesSpace, value);
				lastLabel = nAxesLeft + (int)(i * blockWidth) + Wnd.m_pPaintDC->GetTextExtent(value).cx / 2;
			}
		}
		Wnd.m_pPaintDC->TextOut(nAxesLeft + (int)((0.5) * blockWidth), nAxesBottom + nAxesSpace + nTextSize, "UR");
		Wnd.m_pPaintDC->TextOut(nAxesLeft + (int)((lHistoCount + 1.5) * blockWidth), nAxesBottom + nAxesSpace + nTextSize, "OR");

		//Draw labels:
		CString xLabel, yLabel;
		if (TagCnvFamily[nTagCnvUsed].Valid() && strcmp(TagCnvFamily[nTagCnvUsed].Name(), "") != 0)
			xLabel.Format("Value (%s)", TagCnvFamily[nTagCnvUsed].Name());
		else
			xLabel.Format("Value");

		yLabel.Format("Count");
		
		Wnd.m_pPaintDC->SetTextAlign(TA_BOTTOM | TA_CENTER);
		Wnd.m_pPaintDC->TextOut((nAxesLeft + nAxesRight) / 2, Wnd.m_ClientRect.bottom - nBorderSpace, xLabel);
		
#if (_MSC_VER >= 1400)
		int oldMode = Wnd.m_pPaintDC->SetGraphicsMode(GM_ADVANCED);
		XFORM rotation = {
			0, -1,
			1, 0,
			0, 0};
		XFORM identity = {
			1, 0,
			0, 1,
			0, 0};
		BOOL setTransformResult = Wnd.m_pPaintDC->SetWorldTransform(&rotation);

		Wnd.m_pPaintDC->SetTextAlign(TA_TOP | TA_CENTER);
		Wnd.m_pPaintDC->TextOut(-(nAxesTop + nAxesBottom) / 2, nBorderSpace, yLabel);
		Wnd.m_pPaintDC->SelectObject(oldPen);

		Wnd.m_pPaintDC->SetWorldTransform(&identity);
		Wnd.m_pPaintDC->SetGraphicsMode(oldMode);
#else
		Wnd.m_pPaintDC->SetTextAlign(TA_TOP | TA_LEFT);
		Wnd.m_pPaintDC->TextOut(nAxesLeft, nBorderSpace, yLabel);
#endif
	}
	return true;
}
Esempio n. 3
0
//-----------------------------------------------------------------------------
//!
//-----------------------------------------------------------------------------
void tTideGraph::paintEvent( QPaintEvent* pEvent )
{
    tTideCurrentGraphBase::paintEvent( pEvent );

    int w = contentsRect().width();
    int h = contentsRect().height();

    QPainter p( this );
    p.setRenderHint( QPainter::Antialiasing, true );
    p.setClipRect( contentsRect() );
    QRect r( QPoint(0,0), contentsRect().size() );

    // lets translate the painter so we can work with a 0,0 origin
    p.save();
    p.translate( contentsRect().topLeft() );

    //###### 1) Paint background and the daylight area
    if(m_SunRiseX <= m_SunSetX)
    {
        // left night
        p.fillRect( 0, 0, m_SunRiseX, h, palette().dark() );
        // day
        p.fillRect( m_SunRiseX, 0, m_SunSetX - m_SunRiseX, h, palette().light() );
        // right night
        p.fillRect( m_SunSetX, 0, w - m_SunSetX, h, palette().dark() );
    }
    else if(m_SunRiseX > m_SunSetX)
    {
        // left day
        p.fillRect( 0, 0, m_SunSetX, h, palette().light() );
        // night
        p.fillRect( m_SunSetX, 0, m_SunRiseX - m_SunSetX, h, palette().dark() );
        // right day
        p.fillRect( m_SunRiseX, 0, w - m_SunRiseX, h, palette().light() );
    }

    //###### 2) Add legend backgrounds
    QColor c = palette().text().color();
    c.setAlpha( 127 );
    p.fillRect( 0, h - BOTTOM_MARGIN_HEIGHT, w, BOTTOM_MARGIN_HEIGHT, QBrush( c ) );
    p.fillRect( 0, 0, LEFT_MARGIN_WIDTH, h, palette().base() );

    // we have finished doing work with a 0,0 origin
    p.restore();

    //###### 3) Left depth legend and grid lines
    p.rotate(-90);

    p.setRenderHint( QPainter::Antialiasing, false );
    c.setAlpha( 63 );
    QPen pen( QBrush( c ), 0 );

    qreal rangeDiv = GetRangeDivision( tConvert::Instance()->ToUser(UNITS_DEPTH, m_HeightUnits, static_cast<float>(m_GraphConfig.m_DeltaY)) );
    float stepSize = tConvert::Instance()->UserToBase( UNITS_DEPTH, static_cast<float>(rangeDiv) );
    stepSize = tConvert::Instance()->BaseToSpecifiedUnits(UNITS_DEPTH, m_HeightUnits, stepSize);

    for( qreal pxY = 0, strY = 0; pxY <= m_GraphConfig.m_MaxY; pxY += stepSize, strY += rangeDiv )
    {
        p.setPen( palette().text().color() );
        p.drawText(RotatedTextELeftMargin(0, pxY, 40), Qt::AlignCenter, QString("%1").arg(strY) );
        p.setPen( pen );
        p.drawLine(RotatedGraphToPixel(0, pxY), RotatedGraphToPixel(1, pxY));
    }
    for( qreal pxY = 0, strY = 0; pxY >= m_GraphConfig.m_MinY; pxY -= stepSize, strY += rangeDiv )
    {
        p.setPen( palette().text().color() );
        p.drawText(RotatedTextELeftMargin(0, pxY, 40), Qt::AlignCenter, QString("%1").arg(strY) );
        p.setPen( pen );
        p.drawLine(RotatedGraphToPixel(0, pxY), RotatedGraphToPixel(1, pxY));
    }
    p.rotate(90);
    p.drawLine( QPointF( GraphToPixel(0.25, 0).x(), 0 ), QPointF( GraphToPixel(0.25, 0).x(), h ) );
    p.drawLine( QPointF( GraphToPixel(0.5, 0).x(), 0 ), QPointF( GraphToPixel(0.5, 0).x(), h ) );
    p.drawLine( QPointF( GraphToPixel(0.75, 0).x(), 0 ), QPointF( GraphToPixel(0.75, 0).x(), h ) );
    p.setRenderHint( QPainter::Antialiasing, true );

    //###### 4) Graph and fill the tides spline
    QPainterPath path;
    path.moveTo( GraphToPixel(0, 0) );
    for( int i = 0; i < m_TideHeights.size(); ++i )
    {
        // source data is in 10 minute intervals => 1/144 of a day
        path.lineTo( GraphToPixel( m_TideHeights.at(i).x(), m_TideHeights.at(i).y() ) );        
    }
    // Close the path
    path.lineTo( GraphToPixel(1, 0) );
    path.lineTo( GraphToPixel(0, 0) );

    //###### 5) Fill graph path
    QLinearGradient gradient(0,0,0,h);
    QColor endColor = palette().highlight().color();
    endColor.setAlpha( 191 );
    QColor midColor = palette().highlight().color().lighter( 130 );
    midColor.setAlpha( 191 );
    gradient.setColorAt(0.0, endColor);
    gradient.setColorAt(0.1, endColor);
    gradient.setColorAt(0.5, midColor);
    gradient.setColorAt(0.9, endColor);
    gradient.setColorAt(1.0, endColor);
    p.fillPath(path, gradient);
    
    p.save();
    QPen penGraph( palette().base().color() );
    penGraph.setWidth(2);
    p.setPen(penGraph);
    p.drawPath(path);
    p.restore();        

    //###### 6) Draw over with text
    p.setPen( palette().base().color() );
    qSort(m_TideExtremes);
    for( int i = 0; i < m_TideExtremes.size(); ++i )
    {
        // Convert time into decimal
        qreal timePos = GetTimeF( m_TideExtremes.at(i).first );

        // Draw on height (and compensate for user units)
        float convertedHeight = tConvert::Instance()->ToUser(UNITS_DEPTH, m_HeightUnits, static_cast<float>(m_TideExtremes.at(i).second) );
        QString unitsString = tConvert::Instance()->GetUnitsString( UNITS_DEPTH );
        QString heightString = QString("%1 ").arg(convertedHeight, 2, 'f', qAbs(convertedHeight) > 1 ? 1 : 2) + unitsString;
        QString timeString = m_TideExtremes.at(i).first.toString( tSystemSettings::Instance()->TimeFormatString() );

        QRect boundRectHeight = TextBoundingRect( timePos, 0, fontMetrics().width( heightString ), eBottomMarginHeight );
        QRect boundRectTime = TextBoundingRect( timePos, 0, fontMetrics().width( timeString ), eBottomMarginTime );

        QPen curPen = p.pen();
        if( i < m_TideExtremes.size() - 1 )
        {
            if( m_TideExtremes[i].second < m_TideExtremes[i+1].second )
            {
                p.setPen(Qt::red);
            }
        }
        else
        {
            if( m_TideExtremes[i].second < m_TideExtremes[i-1].second )
            {
                p.setPen(Qt::red);
            }
        }

        p.drawText( boundRectHeight, Qt::AlignCenter, heightString );
        p.drawText( boundRectTime, Qt::AlignCenter,  timeString );
        p.setPen(curPen);
        // Draw on time

        // Draw triangle
    }

    //####### 7) Draw on the sun times
    //(SUN)
    p.setPen( palette().text().color() );
    if(m_SunRiseTime.isValid())
    {
        QString riseString = tr("Sunrise") + " " + m_SunRiseTime.toString( tSystemSettings::Instance()->TimeFormatString() );
        QRect boundSunRise = TextBoundingRect( GetTimeF( m_SunRiseTime ), m_GraphConfig.m_MinY, fontMetrics().width( riseString ), eSunTime);       
        p.drawText(boundSunRise, Qt::AlignCenter, riseString );
    }

    if(m_SunSetTime.isValid())
    {
        QString sunsetString = tr("Sunset") + " " + m_SunSetTime.toString( tSystemSettings::Instance()->TimeFormatString() );
        QRect boundSunSet = TextBoundingRect( GetTimeF( m_SunSetTime ), m_GraphConfig.m_MinY, fontMetrics().width( sunsetString ), eSunTime);
        p.drawText(boundSunSet, Qt::AlignCenter, sunsetString );
    }

    //####### 8) Draw the time and height for the present time
    tDateTime currentDateTime = tDateTime::currentDateTime(); //QDateTime does not know time zone / local time offset.
    if( m_UseUTCTime )
    {
        currentDateTime = currentDateTime.toUTC();
    }
    if(m_ActiveDate.date() == currentDateTime.date())
    {
        qreal currentTime = GetTimeF( currentDateTime.time() );               
        qreal height = GetHeightAtTime( currentTime );
        float convertedHeight = tConvert::Instance()->ToUser(UNITS_DEPTH, m_HeightUnits, static_cast<float>(height) );

        QString unitsString = tConvert::Instance()->GetUnitsString( UNITS_DEPTH );
        QString heightString = QString("%1 ").arg(convertedHeight, 2, 'f', qAbs(convertedHeight) > 1 ? 1 : 2) + unitsString;
        QString timeString = currentDateTime.time().toString( tSystemSettings::Instance()->TimeFormatString() );

        QRect boundCurrentHeight = TextBoundingRect( currentTime, 0, fontMetrics().width( heightString ), eCurrentHeight );
        QRect boundCurrentTime = TextBoundingRect( currentTime, 0, fontMetrics().width( timeString ), eCurrentTime );            

        p.setPen( palette().text().color() );
        p.drawText( boundCurrentHeight, Qt::AlignCenter, heightString ); 
        p.drawText( boundCurrentTime, Qt::AlignCenter, timeString ); 
        QPen penRed(Qt::red);
        p.setPen(penRed);
        p.setRenderHint( QPainter::Antialiasing, false );
        p.drawLine( GraphToPixel(currentTime, m_GraphConfig.m_MinY).toPoint(),
            GraphToPixel(currentTime, m_GraphConfig.m_MaxY).toPoint() - QPoint(0,1) );
    }

}