ACT-CV - Machine Vision for Cognitive Modeling
QtFrameSource.cpp
Go to the documentation of this file.
1 // -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; coding: iso-8859-1; -*-
2 
3 /*
4  ACT-CV - Machine Vision for Cognitive Modeling
5  Copyright (c) 2010 Marc Halbruegge
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 
27 #include "QtFrameSource.h"
28 
29 #include <general/OpenCVHelpers.h>
30 
31 #include <QWebFrame>
32 #include <QApplication>
33 #include <QDesktopWidget>
34 #include <QtNetwork>
35 
36 
37 #include <iostream>
38 #include <boost/algorithm/string/erase.hpp>
39 
40 using namespace std;
41 
42 static QApplication* pApp = nullptr;
43 static void QAppCreate() {
44  if(!pApp) {
45  QNetworkProxyFactory::setUseSystemConfiguration(true);
46 
47  int argc = 0;
48  pApp = new QApplication(argc, nullptr);
49  }
50 }
51 static void QAppTearDown() {
52  if(pApp) {
53  pApp->quit();
54  delete pApp;
55  pApp = nullptr;
56  }
57 }
58 
59 
60 QtFrameSource::QtFrameSource(const char* url, int width, int height)
61  : width_(width),
62  height_(height),
63  image_(cvCreateImage(cvSize(width_,height_),IPL_DEPTH_8U,3)),
64  n_(0),
65  mouseX_(0),
66  mouseY_(0)
67 {
68  pApp->sendPostedEvents();
69  pApp->processEvents();
70 
71  cvZero(image_);
72 
73  page_.mainFrame()->setHtml(QString::fromLatin1("<html></html>"));
74 
75  page_.mainFrame()->load(QUrl::fromUserInput(QString::fromLatin1(url)));
76  page_.mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
77  page_.mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
78  page_.setViewportSize(QSize(width_, height_));
79 
80  pApp->sendPostedEvents();
81  pApp->processEvents();
82 }
83 
85 {
86  cvReleaseImage(&image_);
87 
88  // mh 20130917 experimental
89  QAppTearDown();
90 }
91 
92 bool QtFrameSource::walkTree(const QWebElement& elem) {
93  QWebElement child = elem.firstChild();
94  bool result = !child.isNull();
95  while(!child.isNull()) {
96  bool hasChildren = walkTree(child);
97  if(!hasChildren) {
98  const QRect rect = child.geometry();
99  if(rect.isValid()) {
100  // rect may be empty/null for invisible stuff (?)
101  string tagName = child.tagName().toStdString();
102  if(tagName == "A"
103  || tagName == "TD"
104  || tagName == "DIV"
105  || tagName == "OPTION"
106  || tagName == "INPUT") {
107  string text = child.toPlainText().toStdString();
108  boost::erase_all(text, "\r");
109  boost::erase_all(text, "\n");
110  if(!text.empty()) {
111 #if 1
112  regions_.push_back(RegionInfo());
113  regions_.back().info = text;
114  regions_.back().left = rect.left();
115  regions_.back().top = rect.top();
116  regions_.back().right = rect.right();
117  regions_.back().bottom = rect.bottom();
118 #else
119  cout << text << ":"
120  << child.geometry().center().x() << ","
121  << child.geometry().center().y() << " ";
122  cout.flush();
123 #endif
124  }
125  }
126  }
127  }
128  child = child.nextSibling();
129  }
130  return result;
131 }
132 
133 
135 {
136  pApp->sendPostedEvents();
137  pApp->processEvents();
138 
139  QImage image(page_.mainFrame()->contentsSize(), QImage::Format_ARGB32_Premultiplied);
140  if(!image.isNull()) {
141  image.fill(Qt::transparent);
142  QPainter painter(&image);
143  if(painter.isActive()) {
144  painter.setRenderHint(QPainter::Antialiasing, true);
145  painter.setRenderHint(QPainter::TextAntialiasing, true);
146  painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
147  page_.mainFrame()->documentElement().render(&painter);
148  painter.end();
149 
150  for(int y=0;y<std::min(image.height(),height_);++y) {
151  for(int x=0;x<std::min(image.width(),width_);++x) {
152  cvSet2D(image_,y,x,Rgb2Scalar(image.pixel(x,y)));
153  }
154  }
155 
156 #if 1
157  // test code
158  QWebFrame *frame = page_.mainFrame();
159  if(frame) {
161  QWebElement document = frame->documentElement();
162  regions_.clear();
163  walkTree(document);
164  //cout << endl;
165  }
166 #endif
167  }
168  }
169 
170  ++n_;
171  return image_;
172 }
173 
174 
176  return regions_.size();
177 }
178 
179 const RegionInfo& QtFrameSource::GetInfo(size_t idx) const {
180  return regions_[idx];
181 }
182 
183 
185  return n_;
186 }
187 
188 
189 void QtFrameSource::SetMousePos(int x, int y) {
190  mouseX_ = x;
191  mouseY_ = y;
192 
193 #if QT_VERSION > 0x050000
194  QMouseEvent *pEvent = new QMouseEvent(QEvent::MouseMove, QPointF(x,y), Qt::NoButton, Qt::NoButton, 0);
195 #else
196  QMouseEvent *pEvent = new QMouseEvent(QEvent::MouseMove, QPoint(x,y), Qt::NoButton, Qt::NoButton, 0);
197 #endif
198  pApp->postEvent(&page_, pEvent);
199 
200 }
201 
202 void QtFrameSource::DoClick(int button) {
203 #if QT_VERSION > 0x050000
204  QMouseEvent *pEvent = new QMouseEvent(QEvent::MouseButtonPress,
205  QPointF(mouseX_, mouseY_), Qt::LeftButton, 0, 0);
206  pApp->postEvent(&page_, pEvent);
207  pEvent = new QMouseEvent(QEvent::MouseButtonRelease,
208  QPointF(mouseX_, mouseY_), Qt::LeftButton, 0, 0);
209  pApp->postEvent(&page_, pEvent);
210 #else
211  QMouseEvent *pEvent = new QMouseEvent(QEvent::MouseButtonPress,
212  QPoint(mouseX_, mouseY_), Qt::LeftButton, 0, 0);
213  pApp->postEvent(&page_, pEvent);
214  pEvent = new QMouseEvent(QEvent::MouseButtonRelease,
215  QPoint(mouseX_, mouseY_), Qt::LeftButton, 0, 0);
216  pApp->postEvent(&page_, pEvent);
217 #endif
218 }
219 
221  QKeyEvent *pEvent = new QKeyEvent(QEvent::KeyPress, key, 0);
222  pApp->postEvent(&page_, pEvent);
223  pEvent = new QKeyEvent(QEvent::KeyRelease, key, 0);
224  pApp->postEvent(&page_, pEvent);
225 }
226 
227 //-----------------------------------------------------------------------------
228 
229 
230 QtCaptureSource::QtCaptureSource(int width, int height)
231  : width_(width),
232  height_(height),
233  image_(cvCreateImage(cvSize(width_,height_),IPL_DEPTH_8U,3)),
234  n_(0)
235 {
236  pApp->sendPostedEvents();
237  pApp->processEvents();
238 
239  cvZero(image_);
240 }
241 
243 {
244  cvReleaseImage(&image_);
245 
246  // mh 20130917 experimental
247  QAppTearDown();
248 }
249 
251 {
252  pApp->sendPostedEvents();
253  pApp->processEvents();
254 
255  QScreen *screen = QGuiApplication::primaryScreen();
256  if (screen) {
257  QPixmap pixmap = screen->grabWindow(0);
258  QImage image = pixmap.toImage();
259 
260  for(int y=0;y<std::min(image.height(),height_);++y) {
261  for(int x=0;x<std::min(image.width(),width_);++x) {
262  cvSet2D(image_, y, x, Rgb2Scalar(image.pixel(x,y)));
263  }
264  }
265  }
266 
267  ++n_;
268  return image_;
269 }
270 
271 
273 {
274  return n_;
275 }
276 
277 //-----------------------------------------------------------------------------
278 
280 {
281  QAppCreate();
282 
283  pApp->sendPostedEvents();
284  pApp->processEvents();
285 
286  if(url) {
287  return new QtFrameSource(url);
288  } else {
289  return new QtCaptureSource();
290  }
291 }


ACT-CV - Machine Vision for Cognitive Modeling
© 2015 Marc Halbruegge (actcvlibrary@googlemail.com)