Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8083279
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T17:24:42+00:00 2026-06-05T17:24:42+00:00

Based on a grayscale image and an ordered closed polygon (may be concave), I

  • 0

Based on a grayscale image and an ordered closed polygon (may be concave), I want to get all grayscale values that lie inside a region of interest polygon (as likewise described in SciPy Create 2D Polygon Mask). What is the most performant realisation of that in Qt 4.8? Endpoint should be some kind of QList<double>. Thanks for your advices.

In addition, is it possible to compute a floating point mask (e.g. 0 for outside the polygon, 0.3 for 30% of the pixel area is within the polygon, 1 for completely inside the polygon)? However, that’s just an extra, endpoint would be QPair<double, double> (percentage, value) then. Thanks.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T17:24:43+00:00Added an answer on June 5, 2026 at 5:24 pm

    First you need to scanline convert the polygon into horizontal lines — this is done by getScanLines(). The scanlines are used to sample the image to get all the values within the endpoints of each line, using scanlineScanner().

    Below is a complete, standalone and compileable example I had laying around to show that the scanline algorithm is well behaved. It could be tweaked to calculate the fixed point mask as well. So far a point is included if the scanline covers more than half of it in the horizontal extent (due to round()s in scanlineScanner).

    Upon startup, resize the window and click around to define consecutive points in the polygon. The polygon you see is rendered solely using the scanlines. For comparison, you can enable the outline of the polygon.

    I’m sure the scanline converter could be further optimized. I’m not doing any image sampling, but the scanlineScanner is there to show that it’s a trivial thing to do.

    // https://github.com/KubaO/stackoverflown/tree/master/questions/scanline-converter-11037252
    #define QT_DISABLE_DEPRECATED_BEFORE 5
    #include <QtGui>
    #if QT_VERSION > QT_VERSION_CHECK(5,0,0)
    #include <QtWidgets>
    #endif
    #include <algorithm>
    
    typedef QVector<QPointF> PointVector;
    typedef QVector<QLineF> LineVector;
    
    // A list of vertex indices in the polygon, sorted ascending in their y coordinate
    static QVector<int> sortedVertices(const QPolygonF & poly)
    {
       Q_ASSERT(! poly.isEmpty());
       QVector<int> vertices;
       vertices.reserve(poly.size());
       for (int i = 0; i < poly.size(); ++i) { vertices << i; }
       std::sort(vertices.begin(), vertices.end(), [&](int i, int j){
          return poly[i].y() < poly[j].y();
       });
       return vertices;
    }
    
    // Returns point of intersection of infinite lines ref and target
    static inline QPointF intersect(const QLineF & ref, const QLineF & target)
    {
       QPointF p;
       target.intersect(ref, &p);
       return p;
    }
    
    // Allows accessing polygon vertices using an indirect index into a vector of indices.
    class VertexAccessor {
       const QPolygonF & p;
       const QVector<int> & i;
    public:
       VertexAccessor(const QPolygonF & poly, const QVector<int> & indices) :
          p(poly), i(indices) {}
       inline QPointF operator[](int ii) const {
          return p[i[ii]];
       }
       inline QPointF prev(int ii) const {
          int index = i[ii] - 1;
          if (index < 0) index += p.size();
          return p[index];
       }
       inline QPointF next(int ii) const {
          int index = i[ii] + 1;
          if (index >= p.size()) index -= p.size();
          return p[index];
       }
    };
    
    // Returns a horizontal line scanline rendering of an unconstrained polygon.
    // The lines are generated on an integer grid, but this could be modified for any other grid.
    static LineVector getScanlines(const QPolygonF & poly)
    {
       LineVector lines;
       if (poly.isEmpty()) return lines;
       const QVector<int> indices = sortedVertices(poly);
       VertexAccessor vertex{poly, indices};
       const QRectF bound = poly.boundingRect();
       const auto l = bound.left();
       const auto r = bound.right();
       int ii = 0;
       int yi = qFloor(vertex[0].y());
       QList<int> active;
       PointVector points;
       forever {
          const qreal y = yi;
          const QLineF sweeper{l, y, r, y};
          // Remove vertex from the active list if both lines extending from it are above sweeper
          for (int i = 0; i < active.size(); ) {
             const int ii = active.at(i);
             // Remove vertex
             if (vertex.prev(ii).y() < y && vertex.next(ii).y() < y) {
                active.removeAt(i);
             } else {
                ++ i;
             }
          }
          // Add new vertices to the active list
          while (ii < poly.count() && vertex[ii].y() < y) {
             active << ii++;
          }
          if (ii >= poly.count() && active.isEmpty()) break;
          // Generate sorted intersection points
          points.clear();
          for (auto ii : active) {
             const auto a = vertex[ii];
             auto b = vertex.prev(ii);
             if (b.y() >= y)
                points << intersect(sweeper, QLineF{a, b});
             b = vertex.next(ii);
             if (b.y() >= y)
                points << intersect(sweeper, QLineF{a, b});
          }
          std::sort(points.begin(), points.end(), [](const QPointF & p1, const QPointF & p2){
             return p1.x() < p2.x();
          });
          // Generate horizontal fill segments
          for (int i = 0; i < points.size() - 1; i += 2) {
             lines << QLineF{points.at(i).x(), y, points.at(i+1).x(), y};
          }
          yi++;
       };
       return lines;
    }
    
    QVector<int> scanlineScanner(const QImage & image, const LineVector & tess)
    {
       QVector<int> values;
       for (auto & line : tess) {
          for (int x = round(line.x1()); x <= round(line.x2()); ++ x) {
             values << qGray(image.pixel(x, line.y1()));
          }
       }
       return values;
    }
    
    class Ui : public QWidget
    {
       Q_OBJECT
       QPointF lastPoint;
       QPolygonF polygon;
       LineVector scanlines;
       QGridLayout layout{this};
       QPushButton reset{"Reset"};
       QCheckBox outline{"Outline"};
    public:
       Ui() {
          setMinimumSize(200, 200);
          layout.addItem(new QSpacerItem{0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding}, 0, 0, 1, 3);
          layout.addWidget(&reset, 1, 0);
          layout.addWidget(&outline, 1, 1);
          layout.addItem(new QSpacerItem{0, 0, QSizePolicy::Expanding}, 1, 2);
          reset.setObjectName("reset");
          outline.setObjectName("outline");
          QMetaObject::connectSlotsByName(this);
       }
    protected:
       Q_SLOT void on_reset_clicked() {
          polygon.clear();
          scanlines.clear();
          lastPoint = QPointF{};
          update();
       }
       Q_SLOT void on_outline_stateChanged() {
          update();
       }
       void paintEvent(QPaintEvent *) override {
          QPainter p{this};
          if (false) p.setRenderHint(QPainter::Antialiasing);
          p.setPen("cadetblue");
          if (!polygon.isEmpty() && scanlines.isEmpty()) {
             scanlines = getScanlines(polygon);
             qDebug() << "new scanlines";
          }
          p.drawLines(scanlines);
          if (outline.isChecked()) {
             p.setPen("orangered");
             p.setBrush(Qt::NoBrush);
             p.drawPolygon(polygon);
          }
          if (!lastPoint.isNull()) {
             p.setPen("navy");
             p.drawEllipse(lastPoint, 3, 3);
          }
       }
       void mousePressEvent(QMouseEvent * ev) override {
          lastPoint = ev->posF();
          polygon << ev->posF();
          scanlines.clear();
          update();
       }
    };
    
    int main(int argc, char** argv)
    {
       QApplication app{argc, argv};
       Ui ui;
       ui.show();
       return app.exec();
    }
    
    #include "main.moc"
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have an OCR based iPhone app that takes in grayscale images and thresholds
What I have is a little jQuery based script intended to grayscale an image.
based on .designer.cs, i infer that the menu's arrangement is based on the order
Based on some answers to this question it appears that +alloc does some behind-the-scenes
Based on code suggestions here at stackoverflow, I've tried to extract an image from
I am developing an application that displays 16 bit grayscale images. The UI for
Based on the above subplot: 1) I want to be able to have one
Based on the current uploadify documents, it uses formData (weird all google search results,
Based on what I had read when I started working on the game that
Based on the redirect below, How could I get it to redirect from 2007-2010?

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.