void OnlinePlotter::eventOccured(Event *event) { if(event == 0) { return; } else if(event == mStartEvent) { if(mPlotterProgramValue->get() == "" || mPlotterProgramValue->get().contains("internal", Qt::CaseInsensitive)) { mRunningCalculator = mActiveCalculatorValue->get(); prepareData(mRunningCalculator); emit startProcessing(); } } else if(event == mFinishEvent) { //if the calculator stopped running: if(mPlotterProgramValue->get() == "" || mPlotterProgramValue->get().contains("internal", Qt::CaseInsensitive)) { emit finishedProcessing(); } } }
bool NetworkDynamicsPlotterApplication::setupGui() { //Have to be present before the GUI is constructed. StandardNeuralNetworkFunctions(); StandardConstraintCollection(); mMainWindow = new DynamicsPlotterMainWindow(mEnableSimulator, true); if(mMainWindow != 0) { new NetworkEditorCollection(mMainWindow->getMenu("Tools"), "Network &Editor", false); BoolValueSwitcherAction *runPlotterButton = new BoolValueSwitcherAction("&Run Plotters", DynamicsPlotConstants::VALUE_PLOTTER_EXECUTE); runPlotterButton->setShortcut(tr("Ctrl+r")); mMainWindow->getMenu("Control")->addAction(runPlotterButton); } connect(this, SIGNAL(showGui()), mMainWindow, SLOT(showWindow())); mTimer = new QTimer(); mTimer->setInterval(2000); OnlinePlotter *op = new OnlinePlotter(); //Core::getInstance()->addSystemObject(op); for(int i = 0; i < 6; ++i) { OnlinePlotterWindow *opw = new OnlinePlotterWindow(i); connect(op, SIGNAL(dataPrepared(QString, MatrixValue*, bool)), opw, SLOT(printData(QString, MatrixValue*, bool))); connect(mTimer, SIGNAL(timeout()), opw, SLOT(updateData())); connect(opw, SIGNAL(timerStart()), mTimer, SLOT(start())); connect(op, SIGNAL(startProcessing()), opw, SLOT(processing())); connect(op, SIGNAL(finishedProcessing()), opw, SLOT(finishedProcessing())); } connect(op, SIGNAL(finishedProcessing()), mTimer, SLOT(stop())); //***/Till****// return true; }
void TransformRequest::runRequest() { if (transform != NULL) { transform->transform(inputData,outputData); } else { qWarning() << "[TransformRequest] transform is null, ignoring"; } // qDebug() << "Processor fisnished: " << this << " exec time: " << timer.elapsed() << "ms"; emit finishedProcessing(outputData, messagesList); }
void MemoryPacketModel::launchUpdate(TransformAbstract *transform, int row, int column, int length) { // qDebug() << "update row" << row << "column" << column << "length" << length; if (transform == nullptr || packetsList.size() == 0) return; // nothing to do here if (row < 0 || row >= packetsList.size()) { qCritical() << tr("[MemoryPacketModel::launchUpdate] Row value out-of-bound: %1 T_T").arg(row); return; } if (length < 0) { // all to the end of the list length = packetsList.size() - row; } if (row > packetsList.size() - length) { qCritical() << tr("[MemoryPacketModel::launchUpdate] Row (%1) + length (%2) value is out-of-bound T_T").arg(row).arg(length); return; } TransformAbstract * ta = transformFactory->cloneTransform(transform); if (ta != nullptr) { QList<QByteArray> dataList; for (int i = row; i < row + length; i++) { dataList.append(packetsList.at(i)->getData()); } TransformRequest *tr = new(std::nothrow) TransformRequest( ta, dataList, 0); if (tr == nullptr) { qFatal("Cannot allocate memory for TransformRequest X{"); } connect(tr,SIGNAL(finishedProcessing(QList<QByteArray>,Messages)), this, SLOT(transformRequestFinished(QList<QByteArray>,Messages))); QPair<int,int> coordinate(row, column); transformRequests.insert((quintptr)tr, coordinate); emit readOnlyStateChanged(true); emit sendRequest(tr); } }
void ThreadedProcessor::startRequest(TransformRequest *request) { connect(request, SIGNAL(finishedProcessing(QByteArray,Messages)), this, SLOT(onRequestFinished()),Qt::QueuedConnection); QFuture<void> future = QtConcurrent::run(request, &TransformRequest::runRequest); currentRunning.insert(request, future); }
void ImageProcessor::setConfig(SkinCamConfig newConfig) { lockConfig.lockForWrite(); myConfig = newConfig; //if skin detection is enabled, create one subthread for each filter //or remove unnecessary filters if(myConfig.detectSkinByQuotient && (myConfig.quotientFilters.size() > 0)) { while(subthreads.size() < myConfig.quotientFilters.size()) { subthreads.append(new QThread()); skinTasks.append(new TaskDetectSkinByQuotient()); skinTasks.last()->moveToThread(subthreads.last()); connect(this, SIGNAL(doSkinDetection(MultispectralImage)), skinTasks.last(), SLOT(process(MultispectralImage))); connect(skinTasks.last(), SIGNAL(finishedProcessing(Mat)), this, SLOT(skinDetectionReady(Mat))); connect(skinTasks.last(), SIGNAL(errorProcessing()), this, SLOT(onError())); subthreads.last()->start(); } while (subthreads.size() > myConfig.quotientFilters.size()) { subthreads.last()->quit(); subthreads.last()->wait(); delete subthreads.last(); subthreads.removeLast(); skinTasks.removeLast(); } //assign one filter to each task for(int i = 0; i < skinTasks.size(); i++) skinTasks[i]->setFilter(myConfig.quotientFilters.at(i)); } //if distance estimation is enabled, create a subthread for it if (myConfig.estimateDistance) { //clean old threads, create new while (distThreads.size() > 0) { distThreads.last()->quit(); distThreads.last()->wait(); delete distThreads.last(); distThreads.removeLast(); } distThreads.append(new QThread()); //connect signals & slots for thread distTask = new TaskEstimateDistanceByChromAberr(); distTask->moveToThread(distThreads.last()); connect(this, SIGNAL(doDistanceEstimation(MultispectralImage)), distTask, SLOT(process(MultispectralImage))); connect(this, SIGNAL(setDistEstimParams(int,Mat,int,int)), distTask, SLOT(setParameters(int,Mat,int,int))); connect(distTask, SIGNAL(finishedProcessing(Mat)), this, SLOT(distEstimationReady(Mat))); connect(distTask, SIGNAL(errorProcessing()), this, SLOT(onError())); connect(distTask, SIGNAL(reportBack(int)), this, SLOT(reportFromDistEstimation(int))); distThreads.last()->start(); } lockConfig.unlock(); }
void ImageProcessor::process(MultispectralImage frame) { MultispectralImage frame8Bit; QList<imgDesc> results; quint8 i; Mat filterMask; Mat maskedFCImage; double maxVal = 0; double maxTemp = 0.0; Mat temp; double spread; Mat motionMask; errorOccurred = false; lockConfig.lockForRead(); //main processing tasks //********************* //subtract dark image, if enabled if(myConfig.calibration.subtractDark && !frame.getDarkSubtracted()) { for(i = 1; i < frame.getChannelCount(); i++) { //subtract dark image from current image Mat tmp; cv::subtract(frame.getImageByChannelNumber(i), frame.getDarkImage(), tmp); //set result as new channel image frame.setChannelImage(frame.getWavebands().at(i), tmp); } frame.setDarkSubtracted(true); } //perform skin detection by using quotient filters, if enabled if(myConfig.detectSkinByQuotient && (myConfig.quotientFilters.size() > 0)) { //clear result list skinDetectionResults.clear(); //signal processing of all filters emit doSkinDetection(frame); } //if image depth is more than 8bit, image has to be resampled to be displayed if(frame.getDepth() > 8) { //if automatic contrast is enabled, find the brightest spot in all channels if(myConfig.contrastAutomatic) { //iterate through all bands (except dark) to find maximum value for(i = 1; i < frame.getChannelCount(); i++) { minMaxLoc(frame.getImageByChannelNumber(i), NULL, &maxTemp); if ( maxTemp > maxVal ) { maxVal = maxTemp; } } //subtract contrast dark offset from maximum maxVal -= myConfig.contrastOffset; //slowly increase or decrease contrast value if((maxVal / myConfig.contrastValue) < 220) { myConfig.contrastValue -= (myConfig.contrastValue - (maxVal / 255)) / 10; } else if((maxVal / myConfig.contrastValue) > 250) { myConfig.contrastValue += ((maxVal / 255) - myConfig.contrastValue) / 10; } } //calculate spread factor spread = 1.0 / (double)myConfig.contrastValue; //configure GUI image object frame8Bit.setSize(frame.getWidth(), frame.getHeight()); frame8Bit.setDepth(8); //scale down every band for (i = 0; i < frame.getChannelCount(); i++) { //subtract contrast offset, if enabled Mat tempOffset; if(myConfig.contrastOffset > 0) { subtract(frame.getImageByChannelNumber(i), Scalar(myConfig.contrastOffset), tempOffset); } else { tempOffset = frame.getImageByChannelNumber(i); } //convert to 8 bit using spread factor tempOffset.convertTo(temp, 8, spread ); frame8Bit.setChannelImage(frame.getWavebands().at(i), temp.clone()); } } else { frame8Bit = frame; } //detect edges if(myConfig.edgeDetection) { QMapIterator<qint16, Mat> it(frame8Bit.getImages()); while(it.hasNext()) { it.next(); Mat edges = doEdgeDetection(it.value(), myConfig.edgeThreshold); struct imgDesc edgeResult; edgeResult.desc = QString("Edges %1nm").arg(it.key()); edgeResult.img = edges; results.append(edgeResult); } } //Estimate distance (in separate thread) if (myConfig.estimateDistance) { //make edge mask on selected image Mat edges; if(autoSelectCannyImage) //automatically select sharpest band image for edge detection { Canny(frame8Bit.getImageByChannelNumber(lastSharpestBand), edges, cannyLowThresh, cannyHighThresh); } else //use band image selected by the user (in GUI) { Canny(frame8Bit.getImageByChannelNumber(cannyImage), edges, cannyLowThresh, cannyHighThresh); } //emit signals to distance estimation thread distEstimationResults.clear(); emit setDistEstimParams((int)myConfig.sharpMetric, edges, myConfig.sharpnessNbrhdSize, medianKernel); emit doDistanceEstimation(frame8Bit); //wait for thread to finish while (!errorOccurred && distEstimationResults.size() < 1) //frame8Bit.getChannelCount()-1) { QCoreApplication::processEvents(); } if(errorOccurred) { emit errorProcessing(ImageSourceException("Error in task: estimateDistanceByChromAberr.")); return; } //append distance estimation result to results in order to display them if(!distEstimationResults.empty()) { //get 8 bit image from 1st list entry (at position 0) results.append(distEstimationResults.at(0)); } } //wait for threads to finish: //*************************** //wait until all threads are finished, get results and delete them if(myConfig.detectSkinByQuotient && (myConfig.quotientFilters.size() > 0)) { maskedFCImage = Mat::zeros(frame8Bit.getDarkImage().rows, frame8Bit.getDarkImage().cols, CV_8UC3); //wait until all threads are finished and get results while(!errorOccurred && (myConfig.quotientFilters.size() > skinDetectionResults.size())) { QCoreApplication::processEvents(QEventLoop::AllEvents); } if(errorOccurred) { emit errorProcessing(ImageSourceException("Error in task: detectSkinByQuotients.")); return; } //multiply (cut) the filter masks filterMask = skinDetectionResults.at(0); for(i = 1; i < skinDetectionResults.size(); i++ ) { multiply(filterMask, skinDetectionResults.at(i), filterMask, 1.0); } //remove positive pixels with motion artifacts if(myConfig.suppressMotion && (lastFrame.getChannelCount() == frame.getChannelCount())) { motionMask = Mat::ones(maskedFCImage.rows, maskedFCImage.cols, CV_8UC1); for(i= 0; i < frame.getChannelCount(); i++) { Mat diffF, threshF, thresh; Mat curF, prevF; //get frame channels and convert to float frame.getImageByChannelNumber(i).convertTo(curF, CV_32F); lastFrame.getImageByChannelNumber(i).convertTo(prevF, CV_32F); //calculate absolute difference between current and previous frame absdiff(curF, prevF, diffF); //threshold the absolute difference threshold(diffF, threshF, myConfig.motionThreshold, 1.0, THRESH_BINARY_INV); //convert to 8 bit unsigned threshF.convertTo(thresh, CV_8U); //update motion mask with new thresholded difference mask multiply(motionMask, thresh, motionMask); } //now multiply motion mask with filter mask to remove positive filter results //where there was motion detected multiply(motionMask, filterMask, filterMask); //add motion mask to results struct imgDesc motionResult; motionResult.desc = "Motion"; threshold(motionMask, motionResult.img, 0, 255, THRESH_BINARY_INV) ; results.append(motionResult); } //Morph result: if(myConfig.morphResult) { Mat element(4,4,CV_8U,Scalar(1)); morphologyEx(filterMask, filterMask, MORPH_OPEN, element); } //set mask on top of (8bit) false colour image bitwise_or(maskedFCImage, frame8Bit.getFalseColorImage(myConfig.falseColorChannels), maskedFCImage, filterMask); if(myConfig.showMaskContours) { vector<vector<Point> > contours; CvScalar green = CV_RGB(0,255,0); //CvScalar blue = CV_RGB(0,0,255); findContours(filterMask, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); drawContours(maskedFCImage, contours, -1, green, 2, 8); } struct imgDesc skinMask; struct imgDesc skinResult; skinMask.desc = "QF Mask"; threshold(filterMask, skinMask.img, 0, 255, THRESH_BINARY) ; results.append(skinMask); skinResult.desc = "Masked FC Image"; skinResult.img = maskedFCImage; results.append(skinResult); } lockConfig.unlock(); emit finishedProcessing(frame, frame8Bit, results); lastFrame = frame; }