Matrix<T>& Matrix<T>::operator*=( const qreal& Value ) { Q_ASSERT(constData() && size()); int srcStride1(bytesPerLine()); int srcStride2(bytesPerElement()); if (type() == CV_64F) { Ipp64f* pSrc(reinterpret_cast<Ipp64f*>(data())); const Ipp64f val(static_cast<const Ipp64f>(Value)); IppStatus status(ippmMul_mc_64f(pSrc, srcStride1, srcStride2, val, pSrc, srcStride1, srcStride2, cols(), rows())); Q_ASSERT(status == ippStsNoErr); } else { Q_ASSERT(!"CHECK"); const T mulValue(static_cast<const T>(Value)); for (int rowIndex(0); rowIndex < rows(); rowIndex++) { T* rowPtr(row(rowIndex)); for (int colIndex(0); colIndex < cols(); colIndex++, rowPtr++) { *rowPtr *= mulValue; } } } return *this; }
int AudioEngine::addSource(AudioMsgQueue& dataQ, AudioMsgQueue& statusQ) { SDL_LockAudio(); lock_guard lock(m_Mutex); static int nextID = -1; nextID++; AudioSourcePtr pSrc(new AudioSource(dataQ, statusQ, m_AP.m_SampleRate)); m_AudioSources[nextID] = pSrc; SDL_UnlockAudio(); return nextID; }
void VisibilityLayout::layout(GraphAttributes &GA, const UpwardPlanRep &UPROrig) { UpwardPlanRep UPR = UPROrig; //clear some data for(edge e : GA.constGraph().edges) { GA.bends(e).clear(); } int minGridDist = 1; for(node v : GA.constGraph().nodes) { if (minGridDist < max(GA.height(v), GA.width(v))) minGridDist = (int) max(GA.height(v), GA.width(v)); } minGridDist = max(minGridDist*2+1, m_grid_dist); CombinatorialEmbedding &gamma = UPR.getEmbedding(); //add edge (s,t) adjEntry adjSrc = nullptr; for(adjEntry adj : UPR.getSuperSource()->adjEntries) { if (gamma.rightFace(adj) == gamma.externalFace()) adjSrc = adj; break; } OGDF_ASSERT(adjSrc != nullptr); edge e_st = UPR.newEdge(adjSrc, UPR.getSuperSink()); // on the right gamma.computeFaces(); gamma.setExternalFace(gamma.rightFace(e_st->adjSource())); constructVisibilityRepresentation(UPR); // the preliminary postion NodeArray<int> xPos(UPR); NodeArray<int> yPos(UPR); // node Position for(node v : UPR.nodes) { NodeSegment vVis = nodeToVis[v]; int x = (int) (vVis.x_l + vVis.x_r)/2 ; // median positioning xPos[v] = x; yPos[v] = vVis.y; if (UPR.original(v) != nullptr) { node vOrig = UPR.original(v); //final position GA.x(vOrig) = x * minGridDist; GA.y(vOrig) = vVis.y * minGridDist; } } //compute bendpoints for(edge e : GA.constGraph().edges) { const List<edge> &chain = UPR.chain(e); for(edge eUPR : chain) { EdgeSegment eVis = edgeToVis[eUPR]; if (chain.size() == 1) { if ((yPos[eUPR->target()] - yPos[eUPR->source()]) > 1) { DPoint p1(eVis.x*minGridDist, (yPos[eUPR->source()]+1)*minGridDist); DPoint p2(eVis.x*minGridDist, (yPos[eUPR->target()]-1)*minGridDist); GA.bends(e).pushBack(p1); if (yPos[eUPR->source()]+1 != yPos[eUPR->target()]-1) GA.bends(e).pushBack(p2); } } else { //short edge if ((yPos[eUPR->target()] - yPos[eUPR->source()]) == 1) { if (UPR.original(eUPR->target()) == nullptr) { node tgtUPR = eUPR->target(); DPoint p(xPos[tgtUPR]*minGridDist, yPos[tgtUPR]*minGridDist); GA.bends(e).pushBack(p); } } //long edge else { DPoint p1(eVis.x*minGridDist, (yPos[eUPR->source()]+1)*minGridDist); DPoint p2(eVis.x*minGridDist, (yPos[eUPR->target()]-1)*minGridDist); GA.bends(e).pushBack(p1); if (yPos[eUPR->source()]+1 != yPos[eUPR->target()]-1) GA.bends(e).pushBack(p2); if (UPR.original(eUPR->target()) == nullptr) { node tgtUPR = eUPR->target(); DPoint p(xPos[tgtUPR]*minGridDist, yPos[tgtUPR]*minGridDist); GA.bends(e).pushBack(p); } } } } DPolyline &poly = GA.bends(e); DPoint pSrc(GA.x(e->source()), GA.y(e->source())); DPoint pTgt(GA.x(e->target()), GA.y(e->target())); poly.normalize(pSrc, pTgt); } }
/** * Main function: runs plugin based on its ID * @param plugin ID * @param image to be processed **/ QSharedPointer<nmc::DkImageContainer> DkImageStitchingPlugin::runPlugin(const QString& /*runID*/, QSharedPointer<nmc::DkImageContainer> imgC) const { QString dp = ""; if(imgC) dp = imgC->fileInfo().absolutePath(); QStringList files = QFileDialog::getOpenFileNames(DkPluginInterface::getMainWindow(), tr("Select photos"), dp); if (files.size() != 2) return imgC; // TODO: do NOT use highgui functions - nomacs is a image viewer, so we are much better in loading images than opencv // NOTE: imgC is the currently loaded image, so you could use it as 'reference' image // however, for the final plugin a nice UI has to be done anyhow //cv::Mat reference = cv::imread(files[0].toStdString()); //cv::Mat target = cv::imread(files[1].toStdString()); // loading images using nomacs nmc::DkBasicLoader loader; loader.loadGeneral(files[0]); cv::Mat reference = DkImage::qImage2Mat(loader.image()); loader.loadGeneral(files[0]); cv::Mat target = DkImage::qImage2Mat(loader.image()); cv::Mat grayRef, grayTarget; cv::cvtColor(reference,grayRef,CV_BGR2GRAY); cv::cvtColor(target,grayTarget,CV_BGR2GRAY); // updated for opencv 3 cv::Ptr<cv::Feature2D> f2d = cv::xfeatures2d::SIFT::create(); std::vector<cv::KeyPoint> keypoints1, keypoints2; //cv::SiftFeatureDetector detector; //detector.detect(grayRef,keypoints1); //detector.detect(grayTarget,keypoints2); f2d->detect(grayRef, keypoints1); f2d->detect(grayTarget, keypoints2); cv::Mat descriptor1, descriptor2; //cv::SiftDescriptorExtractor extractor; //extractor.compute(reference,keypoints1,descriptor1); //extractor.compute(target,keypoints2,descriptor2); f2d->compute(grayRef, keypoints1, descriptor1); f2d->compute(grayTarget, keypoints2, descriptor2); // TODO: this is pretty much spaghetti code https://en.wikipedia.org/wiki/Spaghetti_code // you should: // - split the code into different files (e.g. DkStitcher) // - make classes where appropriate // - split the code into functions cv::BFMatcher matcher(cv::NORM_L2); std::vector<cv::DMatch> matches; matcher.match(descriptor1,descriptor2,matches); if (matches.empty()) return imgC; double minDist = matches[0].distance; for (int i = 1; i < matches.size(); ++i) { if (matches[i].distance < minDist) minDist = matches[i].distance; } minDist += 0.1; std::vector<cv::Point2f> queryPts; std::vector<cv::Point2f> trainPts; for (int i = 0; i < matches.size(); ++i) { if (matches[i].distance < 3.0*minDist) { int queryIdx = matches[i].queryIdx; int trainIdx = matches[i].trainIdx; queryPts.push_back(keypoints1[queryIdx].pt); trainPts.push_back(keypoints2[trainIdx].pt); } } ///Obtain the global homography and inliers std::vector<uchar> inliers_mask; cv::Mat globalH = cv::findHomography(queryPts,trainPts, inliers_mask, CV_RANSAC); std::vector<cv::Point2f> inliersTarget; std::vector<cv::Point2f> inliersReference; for (int i = 0; i < inliers_mask.size(); ++i) { if (inliers_mask[i]) { inliersTarget.emplace_back(queryPts[i]); inliersReference.emplace_back(trainPts[i]); } } ///Build the A matrix with the matching points cv::Mat A(2*inliersTarget.size(),9,CV_32F); for (int i = 0; i < inliersTarget.size(); ++i) { const cv::Point2f &pTarget = inliersTarget[i]; const cv::Point2f &pReference = inliersReference[i]; A.at<float>(2*i,0) = 0.0; A.at<float>(2*i,1) = 0.0; A.at<float>(2*i,2) = 0.0; A.at<float>(2*i,3) = -pTarget.x; A.at<float>(2*i,4) = -pTarget.y; A.at<float>(2*i,5) = -1.0; A.at<float>(2*i,6) = pReference.y*pTarget.x; A.at<float>(2*i,7) = pReference.y*pTarget.y; A.at<float>(2*i,8) = pReference.y; A.at<float>(2*i+1,0) = pTarget.x; A.at<float>(2*i+1,1) = pTarget.y; A.at<float>(2*i+1,2) = 1.0; A.at<float>(2*i+1,3) = 0.0; A.at<float>(2*i+1,4) = 0.0; A.at<float>(2*i+1,5) = 0.0; A.at<float>(2*i+1,6) = -pReference.x*pTarget.x; A.at<float>(2*i+1,7) = -pReference.x*pTarget.y; A.at<float>(2*i+1,8) = -pReference.x; } ///Divide the reference image into CX*CY cells and calculate their ///local homographies. const int CX = 100; const int CY = 100; const int cellWidth = (reference.cols+CX-1)/CX; const int cellHeight = (reference.rows+CY-1)/CY; const float sigmaSquared = 12.5*12.5; std::vector<int> cellsType(CX*CY,false); ///(1 is overlapped cell) for (int i = 0; i < inliersTarget.size(); ++i) { const cv::Point2f &pt = inliersTarget[i]; int cellX = (int)(pt.x/cellWidth); int cellY = (int)(pt.y/cellHeight); assert(cellX >= 0 && cellX < CX && cellY >= 0 && cellY < CY); cellsType[cellY*CY+cellX] = true; } std::vector<cv::Mat> localHomographies(CX*CY); cv::Mat Wi(2*inliersTarget.size(),2*inliersTarget.size(),CV_32F,0.0); for (int i = 0; i < CX; ++i) { for (int j = 0; j < CY; ++j) { int centerX = i*cellHeight; int centerY = j*cellWidth; ///Build W matrix for each cell center for (int k = 0; k < inliersTarget.size(); ++k) { cv::Point2f xk = inliersTarget[k]; xk.x = centerX-xk.x; xk.y = centerY-xk.y; float w = exp(-1.0*sqrt(xk.x*xk.x+xk.y*xk.y)/sigmaSquared); Wi.at<float>(2*k,2*k) = w; Wi.at<float>(2*k+1,2*k+1) = w; } ///Calculate local homography for each cell cv::Mat w,u,vt; cv::SVD::compute(Wi*A,w,u,vt); float smallestSv = w.at<float>(0,0); int indexSmallestSv = 0; for (int k = 1; k < w.rows; ++k) { if (w.at<float>(k,0) < smallestSv) { smallestSv = w.at<float>(k,0); indexSmallestSv = k; } } ///Represent the homography as a 3x3 matrix cv::Mat localH(3,3,CV_64F,0.0); for (int k = 0; k < 9; ++k) localH.at<double>(k/3,k%3) = vt.row(indexSmallestSv).at<float>(k); // TODO: crashes here... if (localH.at<float>(2,2) < 0) localH *= -1; localHomographies[i*CY+j] = localH; } } ///Calculate canvas size using global homography cv::Point2f canvasCorners[4]; canvasCorners[0] = cv::Point2f(0,0); canvasCorners[1] = cv::Point2f(reference.cols,0); canvasCorners[2] = cv::Point2f(0,reference.rows); canvasCorners[3] = cv::Point2f(reference.cols,reference.rows); for (int i = 0; i < 4; ++i) { cv::Mat pSrc(3,1,CV_64F,1.0); pSrc.at<double>(0,0) = canvasCorners[i].x; pSrc.at<double>(1,0) = canvasCorners[i].y; cv::Mat pDst = globalH*pSrc; double w = pDst.at<double>(2,0); canvasCorners[i].x = 0.5+(pDst.at<double>(0,0)/w); canvasCorners[i].y = 0.5+(pDst.at<double>(1,0)/w); } int minX = floor(canvasCorners[0].x); int minY = floor(canvasCorners[0].y); int maxX = minX; int maxY = minY; for (int i = 1; i < 4; ++i) { minX = std::min(minX,(int)floor(canvasCorners[i].x)); minY = std::min(minY,(int)floor(canvasCorners[i].y)); maxX = std::max(maxX,(int)floor(canvasCorners[i].x)); maxY = std::max(maxY,(int)floor(canvasCorners[i].y)); } int canvasWidth = std::max(target.cols,maxX)-minX; int canvasHeight = std::max(target.rows,maxY)-minY; ///Calculate translation vector to properly position the ///reference image. cv::Mat T = cv::Mat::eye(3,3,CV_64F); if (minX < 0) T.at<double>(0,2) = -minX; else canvasWidth += minX; if (minY < 0) T.at<double>(1,2) = -minY; else canvasHeight += minY; cv::Mat globalTH = T*globalH; cv::Mat result(canvasHeight,canvasWidth,CV_8UC3,cv::Scalar(0,0,0)); for (int i = 0; i < CX; ++i) { for (int j = 0; j < CY; ++j) { for (int k = 0; k < cellHeight; ++k) { int pX = i*cellHeight+k; if (pX >= reference.rows) break; for (int l = 0; l < cellWidth; ++l) { int pY = j*cellWidth+l; if (pY >= reference.cols) break; cv::Mat ptSrc(3,1,CV_64F,1.0); ptSrc.at<double>(0,0) = pY; ptSrc.at<double>(1,0) = pX; cv::Mat ptDst = (T*localHomographies[i*CY+j])*ptSrc; ptDst /= ptDst.at<double>(2,0); int hX = ptDst.at<double>(0,0); int hY = ptDst.at<double>(1,0); if (hX >= 0 && hX < canvasWidth && hY >= 0 && hY < canvasHeight) result.at<cv::Vec3b>(hY,hX) = reference.at<cv::Vec3b>(pX,pY); } } } } cv::Mat half(result,cv::Rect(std::max(0,-minX),std::max(0,-minY),target.cols,target.rows)); target.copyTo(half); cv::cvtColor(result,result,CV_BGR2RGB); if (!imgC) // TODO: note, the constructor's input _should be_ the filepath not some name! imgC = QSharedPointer<nmc::DkImageContainer>(new nmc::DkImageContainer(QString("panoramic"))); // TODO: add a useful edit name (e.g. Stitching) and remove the empty quote of filepath imgC->setImage(nmc::DkImage::mat2QImage(result),""); return imgC; }
void DominanceLayout::layout(GraphAttributes &GA, const UpwardPlanRep &UPROrig) { UpwardPlanRep UPR = UPROrig; //clear some data for(edge e : GA.constGraph().edges) { GA.bends(e).clear(); } //compute and splite transitiv edges List<edge> splitMe; findTransitiveEdges(UPR, splitMe); for(edge eSplit : splitMe) { UPR.getEmbedding().split(eSplit); } // set up first-/lastout, first-/lastin firstout.init(UPR, nullptr); lastout.init(UPR, nullptr); firstin.init(UPR, nullptr); lastin.init(UPR, nullptr); node s = UPR.getSuperSource(); node t = UPR.getSuperSink(); firstout[t] = lastout[t] = nullptr; firstin[s] = lastin[s] = nullptr; firstin[t] = lastin[t] =t->firstAdj()->theEdge(); adjEntry adjRun = s->firstAdj(); while (UPR.getEmbedding().rightFace(adjRun) != UPR.getEmbedding().externalFace()) { adjRun = adjRun->cyclicSucc(); } lastout[s] = adjRun->theEdge(); firstout[s] = adjRun->cyclicSucc()->theEdge(); for(node v : UPR.nodes) { if (v == t || v == s) continue; adjEntry adj = UPR.leftInEdge(v); firstin[v] = adj->theEdge(); firstout[v] = adj->cyclicSucc()->theEdge(); adjEntry adjRightIn = adj; while (adjRightIn->cyclicPred()->theEdge()->source() != v) adjRightIn = adjRightIn->cyclicPred(); lastin[v] = adjRightIn->theEdge(); lastout[v] = adjRightIn->cyclicPred()->theEdge(); } //compute m_L and m_R for min. area drawing m_L = 0; m_R = 0; for(edge e : UPR.edges) { node src = e->source(); node tgt = e->target(); if (lastin[tgt] == e && firstout[src] == e) m_L++; if (firstin[tgt] == e && lastout[src] == e) m_R++; } // compute preleminary coordinate xPreCoord.init(UPR); yPreCoord.init(UPR); int count = 0; labelX(UPR, s, count); count = 0; labelY(UPR, s, count); // compaction compact(UPR, GA); // map coordinate to GA for(node v : GA.constGraph().nodes) { node vUPR = UPR.copy(v); GA.x(v) = xCoord[vUPR]; GA.y(v) = yCoord[vUPR]; } // add bends to original edges for(edge e : GA.constGraph().edges) { const List<edge> &chain = UPR.chain(e); for(edge eChain : chain) { node tgtUPR = eChain->target(); if (tgtUPR != chain.back()->target()) { DPoint p(xCoord[tgtUPR], yCoord[tgtUPR]); GA.bends(e).pushBack(p); } } } //rotate the drawing for(node v : GA.constGraph().nodes) { double r = sqrt(GA.x(v)*GA.x(v) + GA.y(v)*GA.y(v)); if (r == 0) continue; double alpha = asin(GA.y(v)/r); double yNew = sin(alpha + m_angle)*r; double xNew = cos(alpha + m_angle)*r; GA.x(v) = xNew; GA.y(v) = yNew; } for(edge e : GA.constGraph().edges) { DPolyline &poly = GA.bends(e); DPoint pSrc(GA.x(e->source()), GA.y(e->source())); DPoint pTgt(GA.x(e->target()), GA.y(e->target())); poly.normalize(pSrc, pTgt); for(DPoint &p : poly) { double r = p.distance(DPoint(0,0)); if (r == 0) continue; double alpha = asin( p.m_y/r); double yNew = sin(alpha + m_angle)*r; double xNew = cos(alpha + m_angle)*r; p.m_x = xNew; p.m_y = yNew; } } }