Пример #1
0
void ScanForAxes::scanYAxis(const QImage& img, Q3CanvasLine& scanLine, Q3CanvasLine& bestYLine,
  int& yAxisCol, int& yAxisRowMin, int& yAxisRowMax)
{
  ASSERT_ENGAUGE(img.width() > 2);

  // y axis scan starts at left and goes right
  bestYLine.setPoints(0, 0, 0, img.height() - 1);
  bestYLine.show();

  // weight starts off at max value of 1 at left, and tapers off to 0 at right
  double weight = 1.0;
  double dWeight = 1.0 / img.width();

  yAxisCol = 0;
  double highestCorrelation = 0.0;
  int col, row;
  bool scanEffect = DefaultSettings::instance().getScanForAxesScanEffect();
  Discretize discretize;
  for (col = 0; col < img.width(); col++)
  {
    scanLine.setPoints(col, 0, col, img.height() - 1);

    double correlation = 0.0;
    for (row = 0; row < img.height(); row++)
      if (col + 1 < img.width())
      {
        // perform one-dimensional convolution with finite step function. only two-pixel
        // wide step function convolution kernel is needed since it will pick up axes of any width,
        // plus its small value reduces number of computations
        int pixelHigh = (discretize.processedPixelIsOn(img, col + 1, row) ?
          PIXEL_DARK :
          PIXEL_LIGHT); // should be dark at edge of axis
        int pixelLow = (discretize.processedPixelIsOn(img, col, row) ?
          PIXEL_DARK :
          PIXEL_LIGHT); // should be light at edge of axis

        correlation += pixelHigh - pixelLow;
      }

    if (weight * correlation > highestCorrelation)
    {
      yAxisCol = col + 1; // we want the column with the black values
      highestCorrelation = correlation;
      bestYLine.setPoints(yAxisCol, 0, yAxisCol, img.height() - 1);

      updateView(img); // update so user can see newest axis candidate
    }

    if (scanEffect)
      updateView(img); // update so user sees nice scanning effect as scanLine moves

    weight -= dWeight;
  }

  // get endpoints
  AxisSlice colSlice(img.height());
  for (row = 0; row < img.height(); row++)
    colSlice [row] = (img.pixel(yAxisCol, row) == QColor(Qt::black).rgb());
  scanAxisForLowEndpoint(colSlice, yAxisRowMin);
  scanAxisForHighEndpoint(colSlice, yAxisRowMax);

  // shrink line down to the actual axis
  bestYLine.setPoints(yAxisCol, yAxisRowMin, yAxisCol, yAxisRowMax);
  updateView(img);
}
Пример #2
0
void ColorChooser::loadHistogram(const QImage* imageOriginal,
  DiscretizeMethod method, int colorAttributeMax, Q3PtrList<Q3CanvasLine>* histogram,
  QRgb rgbBg, QProgressDialog* dlg)
{
  ASSERT_ENGAUGE(
    (method == DiscretizeIntensity) ||
    (method == DiscretizeForeground) ||
    (method == DiscretizeHue) ||
    (method == DiscretizeSaturation) ||
    (method == DiscretizeValue));

  // remove any stale points
  ASSERT_ENGAUGE(histogram != 0);
  histogram->clear();
    
  int *bins = new int [colorAttributeMax + 1];
  CHECK_PTR_ENGAUGE(bins);

  int i;
  for (i = 0; i <= colorAttributeMax; i++)
    bins [i] = 0;

  Discretize discretize;
  int x, y, value, rBg, gBg, bBg;
  QColor color(rgbBg);
  color.rgb(&rBg, &gBg, &bBg);
  for (x = 0; x < imageOriginal->width(); x++)
  {
    for (y = 0; y < imageOriginal->height(); y++)
    {
      if (method == DiscretizeForeground)
        value = discretize.discretizeValueForeground(imageOriginal, x, y, method, rBg, gBg, bBg);
      else
        value = discretize.discretizeValueNotForeground(imageOriginal, x, y, method);

      bins [value] += 1;
    }

    // update progress bar
    ASSERT_ENGAUGE(dlg != 0);
    dlg->setValue(imageOriginal->width() * method + x);
  }
  
  // represent histograms as lines on canvas
  int xOld = ChooserPadding, yOld = m_chooserHeight - 1, xNew, yNew;
  double pixelCount = (double) (imageOriginal->width() * imageOriginal->height());
  for (i = 0; i <= colorAttributeMax + 1; i++)
  {
    if (i < colorAttributeMax + 1)
    {
      // convert bin count to log scale so small bin counts are still visible
      xNew = ChooserPadding + (int) (((ChooserWidth - 1) * i) / (double) (colorAttributeMax) + 0.5);
      int binCount = bins [i];
      if (binCount < 1)
        binCount = 1;
      yNew = (int) ((m_chooserHeight - 1.0) * (1.0 - log((double) binCount) / log(pixelCount)) + 0.5);

      if (yNew < 0)
        yNew = 0;
      if (yNew > m_chooserHeight - 1)
        yNew = m_chooserHeight - 1;
    }
    else
    {
      xNew = ChooserPadding + ChooserWidth;
      yNew = m_chooserHeight - 1;
    }

    Q3CanvasLine* line = new Q3CanvasLine(chooserCanvas);
    CHECK_PTR_ENGAUGE(line);

    line->setPoints(xOld, yOld, xNew, yNew);

    histogram->append(line);

    xOld = xNew;
    yOld = yNew;
  }

  ASSERT_ENGAUGE(bins != 0);
  delete[] bins;
}
Пример #3
0
		// creates a polygon from a given vector RegularData1D * data
		void RegularData1DWidget::createPlot()
		{
			// no data => no polygon
			if (data_ == 0 ||
					data_->size() == 0) 
			{
				return;
			}

			// find the data min and max
			float min = (*data_)[0];
			float max = (*data_)[0];
			float dif_min = min;
			float old = min; //last point

			if (dif_min == 0) dif_min = 1;

			for (int i=0; i<(int)data_->size(); i++)
			{
				if ((*data_)[i] >= max) max = (*data_)[i];
				if ((*data_)[i] <= min) min = (*data_)[i];

				float dif = (*data_)[i] - old;

				if ( (dif > 1e-3) && (dif < dif_min) ) 
				{
					dif_min = dif;
				}

				old = (*data_)[i];
			}

			int height_ = (int)ceil(((max-min) / dif_min) * 5);
		 
			if (height_ > 1000)
			{
				// the resulting picture would be much too large
				height_ = 1000;
				dif_min = (max - min)/200.;
			}	

			// resize the canvas to fit the data
			canvas_.resize(5*(data_->size()+2), height_+10);

			int x_new;
			int y_new;
			int x_old = 5;
			int y_old = height_+5 - (int)((((*data_)[0]-min)/dif_min)*5);
			Q3CanvasLine *ql;

			try
			{
				for (int i=0; i<(int)data_->size(); i++)
				{
					x_new = 5*(i+1);
					y_new = height_+5 - (int)(((data_->getData(i)-min)/dif_min)*5);
					
					ql = new Q3CanvasLine(&canvas_);
					ql->setPen(diagram_color_);
					ql->show();
					ql->setPoints(x_old, y_old, x_new, y_new);
					objects_.push_back(dynamic_cast<Q3CanvasItem*> (ql));

					x_old = x_new;
					y_old = y_new;
				}
			}
			catch(...)
			{
				setStatusbarText("Error: Point in dataset out of grid!");
				Log.error() << "Error: Point in dataset out of grid!" << std::endl;
				return;
			}

			//add the x-axis
			ql = new Q3CanvasLine(&canvas_);
			int startx = 1;
			int starty = height_+5 - (int)/*round*/(((startx-min)/dif_min)*5);
			int endx   = data_->size()*5;
			ql->setPoints(startx, starty, endx, starty);
			ql->setPen(axis_color_);
			ql->show();
			objects_.push_back(dynamic_cast<Q3CanvasItem*> (ql));
				
			//add the y-axis	
			ql = new Q3CanvasLine(&canvas_);
			startx = 4;
			starty = 0;
			int endy   = height_+5 - (int)/*round*/((((*data_)[endx]-min)/dif_min)*5);
			ql->setPoints(startx, starty, startx, endy);
			ql->setPen(QColor(Qt::red));
			ql->show();
			objects_.push_back(dynamic_cast<Q3CanvasItem*> (ql));
		}
Пример #4
0
QRect CEdge::drawTree( Q3Canvas* canvas, int left, int depth, StringToString* filter )
{
	int X_PADDING = 10;
	int Y_SPACING = 30;

//	int X_MARGIN = 10; unused variable 'X_Margin'
	int Y_MARGIN = 10;

	//================================================

	Q3CanvasItem* edge = new Q3CanvasText( LHS(), canvas ),
			   * leaf = NULL;
	Q3CanvasLine* line;

	m_CanvasItems.clear();
	m_CanvasItems.append( edge );

	int myLeft = left,
		myTop = ( depth * Y_SPACING ) + Y_MARGIN,
		myCenterX,
		myBottom,
		childCenterX,
		childLeft,
		childTop,
		shiftAmount;

	Q3ValueList<QRect> daughterBoundingRectangles;
	Q3ValueList<QRect>::iterator it;

	QRect myBoundingRect, rectangle;
	myBoundingRect.setTop( myTop );
	myBoundingRect.setLeft( myLeft );
	myBoundingRect.setBottom( myTop + edge->boundingRect().height() - 1 );
	myBoundingRect.setRight( myLeft + edge->boundingRect().width() - 1 );
	
	int count = 0;
//	bool first = TRUE; unused variable 'first'

	CEdge* daughter;
	for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() )
	{
		daughterBoundingRectangles.append( rectangle );

		daughterBoundingRectangles[count] = daughter->drawTree( canvas, left, depth + 1, filter );

		// Adjust left position based on bounding rectangle of last daughter
		left = daughterBoundingRectangles[count].right() + X_PADDING;

		count++;
	}

	if( m_Daughters.isEmpty() )
	{
		// Create leaf node
		childLeft = myLeft;
		childTop = ( ( depth + 1 ) * Y_SPACING ) + Y_MARGIN;

		leaf = new Q3CanvasText( Filter( filter, RHS() ), canvas );
		m_CanvasItems.append( leaf );

		leaf->move( childLeft, childTop );
		leaf->show();

		// Adjust my bounding rect
		if( leaf->boundingRect().right() > myBoundingRect.right() ) myBoundingRect.setRight( leaf->boundingRect().right() );
		myBoundingRect.setBottom( leaf->boundingRect().bottom() );
	}
	else
	{
		for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it )
		{
			// Adjust my bounding rect
			if( (*it).right() > myBoundingRect.right() ) myBoundingRect.setRight( (*it).right() );
			if( (*it).bottom() > myBoundingRect.bottom() ) myBoundingRect.setBottom( (*it).bottom() );
		}
	}
	
	if( myBoundingRect.width() == edge->boundingRect().width() ) 
	{
		// Shift all children to the right
		if( m_Daughters.isEmpty() )
		{
			shiftAmount = int (( myBoundingRect.width() - leaf->boundingRect().width() ) / 2.0);

			leaf->move( leaf->boundingRect().left() + shiftAmount, leaf->boundingRect().top() );
			leaf->show();
		}
		else
		{
			shiftAmount = int (( myBoundingRect.width() - ( daughterBoundingRectangles.last().right() - daughterBoundingRectangles.first().left() ) ) / 2.0);
			
			for( daughter = m_Daughters.first(); daughter; daughter = m_Daughters.next() )
			{
				daughter->shiftTree( canvas, shiftAmount, 0 );
			}

			for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it )
			{
				// Adjust the bounding rect position
				(*it).setLeft( (*it).left() + shiftAmount );
				(*it).setRight( (*it).right() + shiftAmount );
			}
		}
	}
	else myLeft = ( myBoundingRect.right() - ( myBoundingRect.width() / 2 ) ) - ( edge->boundingRect().width() / 2 );


	if( myLeft < myBoundingRect.left() ) myLeft = myBoundingRect.left();
	edge->move( myLeft, myTop );

	// Draw lines to daughter nodes
	if( m_Daughters.isEmpty() )
	{
		myCenterX = edge->boundingRect().center().x();
		myBottom = edge->boundingRect().bottom();

		childCenterX = leaf->boundingRect().center().x();
		childTop = leaf->boundingRect().top();

		if( myCenterX - childCenterX == 1 || myCenterX - childCenterX == -1 ) myCenterX = childCenterX;

		line = new Q3CanvasLine( canvas );
		line->setPoints( myCenterX, myBottom, childCenterX, childTop );
		line->show();

		m_CanvasItems.append( line );
	}
	else
	{
		Q3ValueList<QRect>::iterator it;
		for( it = daughterBoundingRectangles.begin(); it != daughterBoundingRectangles.end(); ++it )
		{
			myCenterX = edge->boundingRect().center().x();
			myBottom = edge->boundingRect().bottom();

			childCenterX = (*it).center().x();
			childTop = (*it).top();

			if( myCenterX - childCenterX == 1 || myCenterX - childCenterX == -1 ) myCenterX = childCenterX;

			line = new Q3CanvasLine( canvas );
			line->setPoints( myCenterX, myBottom, childCenterX, childTop );
			line->show();

			m_CanvasItems.append( line );
		}
	}

	edge->show();
	canvas->update();

	return myBoundingRect;
}