Exemple #1
0
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;
}