//general processing function of UVDisparity based function cv::Mat UVDisparity::Process(cv::Mat& img_L, cv::Mat& disp_sgbm, VisualOdometryStereo& vo, cv::Mat& xyz, cv::Mat& roi_mask, cv::Mat& ground_mask, double& pitch1, double& pitch2) { cv::Mat mask_moving; calVDisparity(disp_sgbm,xyz); //sequentially estimate pitch angles by Kalman Filter vector<cv::Mat> pitch_measures; pitch_measures = Pitch_Classify(xyz,ground_mask); pitch1_KF->predict(); pitch1_KF->correct(pitch_measures[0]); pitch2_KF->predict(); pitch2_KF->correct(pitch_measures[1]); pitch1 = pitch_measures[0].at<float>(0); pitch2 = pitch_measures[1].at<float>(0); //Improve 3D reconstruction results by pitch angles correct3DPoints(xyz,roi_,pitch1_KF->statePost.at<float>(0),pitch2_KF->statePost.at<float>(0)); //set image ROI according to ROI3D (ROI within a 3D space) setImageROI(xyz, roi_mask); //filter inliers and outliers filterInOut(img_L,roi_mask,disp_sgbm,vo,pitch1); //calculate Udisparity image calUDisparity(disp_sgbm,xyz,roi_mask,ground_mask); //using sigmoid function to adjust Udisparity image for segmentation double scale = 0.02, range = 32; adjustUdisIntense(scale,range); //Find all possible segmentation findAllMasks(vo,img_L,xyz,roi_mask); if(masks_.size()>0) { //merge overlapped masks mergeMasks(); //improve the segments by inliers verifyByInliers(vo,img_L); } //perform segmentation in disparity image segmentation(disp_sgbm,img_L,roi_mask,mask_moving); //demonstration cv::Mat img_show; img_L.copyTo(img_show,mask_moving); cv::imshow("moving",img_show); cv::waitKey(1); masks_.clear(); return mask_moving; }
PowertfDialog::PowertfDialog(cv::Mat& img, QWidget *parent) : QDialog(parent) { r = 1; c = 1; b = 0; img.copyTo(image); pimage = &img; rSlider = new QSlider(Qt::Horizontal); rSlider->setRange(0,10); rSlider->setValue(r); cSlider = new QSlider(Qt::Horizontal); cSlider->setRange(0,10); cSlider->setValue(c); bSlider = new QSlider(Qt::Horizontal); bSlider->setRange(0,10); bSlider->setValue(b); rSBx = new QSpinBox(); rSBx->setRange(0,10); rSBx->setValue(r); cSBx = new QSpinBox(); cSBx->setRange(0,10); cSBx->setValue(c); bSBx = new QSpinBox(); bSBx->setRange(0,10); bSBx->setValue(b); connect(rSlider,SIGNAL(valueChanged(int)),this,SLOT(rChanged(int))); connect(cSlider,SIGNAL(valueChanged(int)),this,SLOT(cChanged(int))); connect(bSlider,SIGNAL(valueChanged(int)),this,SLOT(bChanged(int))); connect(rSlider,SIGNAL(valueChanged(int)),rSBx,SLOT(setValue(int))); connect(cSlider,SIGNAL(valueChanged(int)),cSBx,SLOT(setValue(int))); connect(bSlider,SIGNAL(valueChanged(int)),bSBx,SLOT(setValue(int))); connect(rSBx,SIGNAL(valueChanged(int)),this,SLOT(rChanged(int))); connect(cSBx,SIGNAL(valueChanged(int)),this,SLOT(cChanged(int))); connect(bSBx,SIGNAL(valueChanged(int)),this,SLOT(bChanged(int))); connect(rSBx,SIGNAL(valueChanged(int)),rSlider,SLOT(setValue(int))); connect(cSBx,SIGNAL(valueChanged(int)),cSlider,SLOT(setValue(int))); connect(bSBx,SIGNAL(valueChanged(int)),bSlider,SLOT(setValue(int))); rLabel = new QLabel(tr("r")); cLabel = new QLabel(tr("c")); bLabel = new QLabel(tr("b")); okButton = new QPushButton(tr("&OK")); okButton->setDefault(true); okButton->setEnabled(true); connect(okButton, SIGNAL(clicked()), this, SLOT(okClicked())); closeButton = new QPushButton(tr("&Close")); connect(closeButton, SIGNAL(clicked()), this, SLOT(closePowertf())); QHBoxLayout *rLayout = new QHBoxLayout; rLayout->addWidget(rLabel); rLayout->addWidget(rSlider); rLayout->addWidget(rSBx); QHBoxLayout *cLayout = new QHBoxLayout; cLayout->addWidget(cLabel); cLayout->addWidget(cSlider); cLayout->addWidget(cSBx); QHBoxLayout *bLayout = new QHBoxLayout; bLayout->addWidget(bLabel); bLayout->addWidget(bSlider); bLayout->addWidget(bSBx); QVBoxLayout *leftLayout = new QVBoxLayout; leftLayout->addLayout(rLayout); leftLayout->addLayout(cLayout); leftLayout->addLayout(bLayout); QVBoxLayout *rightLayout = new QVBoxLayout; rightLayout->addWidget(okButton); rightLayout->addWidget(closeButton); rightLayout->addStretch(); QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->addLayout(leftLayout); mainLayout->addLayout(rightLayout); setLayout(mainLayout); setWindowTitle(tr("Power Tranform")); setFixedHeight(sizeHint().height()); }
cv::Mat makeFrame(cv::Mat control, cv::Mat interaction, cv::Mat fill, unsigned char threshold, int blurkernelsize, int offsetx, int offsety ) { //take the absolute difference between the interaction and the //control images and store it in diff cv::Mat diff; cv::absdiff(control, interaction, diff); //initialize an image to store the final result cv::Mat result = cv::Mat::zeros( fill.rows, fill.cols, fill.type() ); //initialize a blank mask cv::Mat mask = cv::Mat::zeros(control.rows, control.cols, CV_8UC1); //for every pixel in diff... for(int i = 0; i < diff.rows; i++) { for(int j = 0; j < diff.cols; j++) { cv::Vec3b pixel = diff.at<cv::Vec3b>(i, j); //...if the absolute value of the pixel exceeds the threshold, //set corresponding mask's pixel to white. //Otherwise, leave it black. /* if(sqrt(pixel[0] * pixel[0] + pixel[1] * pixel[1] + pixel[2] * pixel[2] ) >= threshold ) /*/ if(cv::max( cv::max(pixel[0], pixel[1]), pixel[2] ) >= threshold ) //*/ { mask.at<unsigned char>(i, j) = 255; } } } //apply median-blur to mask with kernel size of blurkernelsize cv::Mat blurredmask; cv::medianBlur(mask, blurredmask, blurkernelsize); //resize mask's resolution to math fill's cv::resize( blurredmask, blurredmask, cv::Size(fill.cols, fill.rows) ); cv::Mat roit; cv::Mat finalmask = cv::Mat::zeros(fill.rows, fill.cols, blurredmask.type() ); if(offsetx >= 0) { if(offsety >= 0) { roit = cv::Mat(blurredmask, cv::Range(0, blurredmask.rows - offsety), cv::Range(0, blurredmask.cols - offsetx) ); roit.copyTo(finalmask(cv::Rect(offsetx, offsety, roit.cols, roit.rows ) ) ); } else { roit = cv::Mat(blurredmask, cv::Range(-offsety, blurredmask.rows), cv::Range(0, blurredmask.cols - offsetx) ); roit.copyTo( finalmask(cv::Rect(offsetx, 0, roit.cols, roit.rows)) ); } } else { if(offsety >= 0) { roit = cv::Mat(blurredmask, cv::Range(0, blurredmask.rows - offsety), cv::Range(-offsetx, blurredmask.cols) ); roit.copyTo( finalmask(cv::Rect(0, offsety, roit.cols, roit.rows)) ); } else { roit = cv::Mat(blurredmask, cv::Range(-offsety, blurredmask.rows), cv::Range(-offsetx, blurredmask.cols) ); roit.copyTo( finalmask(cv::Rect(0, 0, roit.cols, roit.rows)) ); } } //apply mask to fill image and return it fill.copyTo(result, finalmask); return result; }
//! Processes a frame and returns output image bool VideoTrackingSample::processFrame(const cv::Mat& inputFrame, cv::Mat& outputFrame) { inputFrame.copyTo(outputFrame); getGray(inputFrame, m_nextImg); if (m_activeTrackingAlgorithm == TrackingAlgorithmKLT) { if (m_mask.rows != inputFrame.rows || m_mask.cols != inputFrame.cols) m_mask.create(inputFrame.rows, inputFrame.cols, CV_8UC1); if (m_prevPts.size() > 0) { cv::calcOpticalFlowPyrLK(m_prevImg, m_nextImg, m_prevPts, m_nextPts, m_status, m_error); } m_mask = cv::Scalar(255); std::vector<cv::Point2f> trackedPts; for (size_t i=0; i<m_status.size(); i++) { if (m_status[i]) { trackedPts.push_back(m_nextPts[i]); cv::circle(m_mask, m_prevPts[i], 15, cv::Scalar(0), -1); cv::line(outputFrame, m_prevPts[i], m_nextPts[i], cv::Scalar(0,250,0)); cv::circle(outputFrame, m_nextPts[i], 3, cv::Scalar(0,250,0), -1); } } bool needDetectAdditionalPoints = trackedPts.size() < m_maxNumberOfPoints; if (needDetectAdditionalPoints) { m_detector->detect(m_nextImg, m_nextKeypoints, m_mask); int pointsToDetect = m_maxNumberOfPoints - trackedPts.size(); if (m_nextKeypoints.size() > pointsToDetect) { std::random_shuffle(m_nextKeypoints.begin(), m_nextKeypoints.end()); m_nextKeypoints.resize(pointsToDetect); } std::cout << "Detected additional " << m_nextKeypoints.size() << " points" << std::endl; for (size_t i=0; i<m_nextKeypoints.size(); i++) { trackedPts.push_back(m_nextKeypoints[i].pt); cv::circle(outputFrame, m_nextKeypoints[i].pt, 5, cv::Scalar(255,0,255), -1); } } m_prevPts = trackedPts; m_nextImg.copyTo(m_prevImg); } if (m_activeTrackingAlgorithm == TrackingAlgorithmORB) { m_orbFeatureEngine(m_nextImg, cv::Mat(), m_nextKeypoints, m_nextDescriptors); if (m_prevKeypoints.size() > 0) { std::vector< std::vector<cv::DMatch> > matches; m_orbMatcher.radiusMatch(m_nextDescriptors, m_prevDescriptors, matches, 10); for (size_t i=0; i<matches.size(); i++) { cv::Point prevPt = m_prevKeypoints[matches[i][0].trainIdx].pt; cv::Point nextPt = m_nextKeypoints[matches[i][0].queryIdx].pt; cv::circle(outputFrame, prevPt, 5, cv::Scalar(250,0,250), -1); cv::line(outputFrame, prevPt, nextPt, cv::Scalar(0,250,0)); cv::circle(outputFrame, nextPt, 3, cv::Scalar(0,250,0), -1); } } m_prevKeypoints.swap(m_nextKeypoints); m_nextDescriptors.copyTo(m_prevDescriptors); } else if(m_activeTrackingAlgorithm == TrackingAlgorithmBRIEF) { m_fastDetector->detect(m_nextImg, m_nextKeypoints); m_briefExtractor->compute(m_nextImg, m_nextKeypoints, m_nextDescriptors); if (m_prevKeypoints.size() > 0) { std::vector< std::vector<cv::DMatch> > matches; m_orbMatcher.radiusMatch(m_nextDescriptors, m_prevDescriptors, matches, 10); for (size_t i=0; i<matches.size(); i++) { cv::Point prevPt = m_prevKeypoints[matches[i][0].trainIdx].pt; cv::Point nextPt = m_nextKeypoints[matches[i][0].queryIdx].pt; cv::circle(outputFrame, prevPt, 5, cv::Scalar(250,0,250), -1); cv::line(outputFrame, prevPt, nextPt, cv::Scalar(0,250,0)); cv::circle(outputFrame, nextPt, 3, cv::Scalar(0,250,0), -1); } } m_prevKeypoints.swap(m_nextKeypoints); m_nextDescriptors.copyTo(m_prevDescriptors); } return true; }
// Contructor reconstructor::reconstructor(cv::Mat &img) { cont = 0; img.copyTo(inImg); img.copyTo(outImg); }
PERF_TEST_P(Sz, DISABLED_GeneralizedHoughGuil, CUDA_TYPICAL_MAT_SIZES) { declare.time(10); const cv::Size imageSize = GetParam(); const cv::Mat templ = readImage("cv/shared/templ.png", cv::IMREAD_GRAYSCALE); ASSERT_FALSE(templ.empty()); cv::Mat image(imageSize, CV_8UC1, cv::Scalar::all(0)); templ.copyTo(image(cv::Rect(50, 50, templ.cols, templ.rows))); cv::RNG rng(123456789); const int objCount = rng.uniform(5, 15); for (int i = 0; i < objCount; ++i) { double scale = rng.uniform(0.7, 1.3); bool rotate = 1 == rng.uniform(0, 2); cv::Mat obj; cv::resize(templ, obj, cv::Size(), scale, scale); if (rotate) obj = obj.t(); cv::Point pos; pos.x = rng.uniform(0, image.cols - obj.cols); pos.y = rng.uniform(0, image.rows - obj.rows); cv::Mat roi = image(cv::Rect(pos, obj.size())); cv::add(roi, obj, roi); } cv::Mat edges; cv::Canny(image, edges, 50, 100); cv::Mat dx, dy; cv::Sobel(image, dx, CV_32F, 1, 0); cv::Sobel(image, dy, CV_32F, 0, 1); if (PERF_RUN_CUDA()) { cv::Ptr<cv::GeneralizedHoughGuil> alg = cv::cuda::createGeneralizedHoughGuil(); alg->setMaxAngle(90.0); alg->setAngleStep(2.0); const cv::cuda::GpuMat d_edges(edges); const cv::cuda::GpuMat d_dx(dx); const cv::cuda::GpuMat d_dy(dy); cv::cuda::GpuMat positions; alg->setTemplate(cv::cuda::GpuMat(templ)); TEST_CYCLE() alg->detect(d_edges, d_dx, d_dy, positions); } else { cv::Ptr<cv::GeneralizedHoughGuil> alg = cv::createGeneralizedHoughGuil(); alg->setMaxAngle(90.0); alg->setAngleStep(2.0); cv::Mat positions; alg->setTemplate(templ); TEST_CYCLE() alg->detect(edges, dx, dy, positions); } // The algorithm is not stable yet. SANITY_CHECK_NOTHING(); }
bool ImageGenerator::InitMat(cv::Mat &frame) // for video interface { // image_.release(); // ?? frame.copyTo(image_); return true; }
void Image::operator()(const cv::Mat& frame) { frame.copyTo(img); }
Image::Image(const cv::Mat& frame) { frame.copyTo(img); }
// corners (z_all_l, z_all_r) and status are output variables void trackFeatures(const cv::Mat &img_l, const cv::Mat &img_r, std::vector<cv::Point2f> &features_l, std::vector<cv::Point2f> &features_r, std::vector<int> &status, int stereo, int camNumber) { if (!img_l.data) throw "Left image is invalid"; if (stereo && !img_r.data) throw "Right image is invalid"; unsigned int numPoints = status.size(); features_l.resize(numPoints); std::fill(features_l.begin(), features_l.end(), cv::Point2f(-100, -100)); features_r.resize(numPoints); std::fill(features_r.begin(), features_r.end(), cv::Point2f(-100, -100)); for (size_t i = 0; i < status.size() && i < numPoints; ++i) { if (status[i] == 1) { prev_status[i] = 1; } else { prev_status[i] = 0; // if updateVect[i] == 0 feature is inactive, == 2 request new feature } } std::vector<unsigned char> status_left, status_right; std::vector<cv::Point2f> cur_corners, right_corners; std::vector<float> error; if (!prev_img[camNumber].empty()) { if (!prev_corners[camNumber].empty()) { cv::calcOpticalFlowPyrLK(prev_img[camNumber], img_l, prev_corners[camNumber], cur_corners, status_left, error, cv::Size(9, 9), 3); prev_corners[camNumber] = cur_corners; if (stereo == 2) cv::calcOpticalFlowPyrLK(img_l, img_r, prev_corners[camNumber], right_corners, status_right, error, cv::Size(9, 9), 3); for (size_t i = 0; i < prev_corners[camNumber].size() && i < numPoints; ++i) { if (!(prev_status[i] && status_left[i] && (stereo != 2 || status_right[i]))) prev_status[i] = 0; if (prev_status[i] == 1) { if (prev_corners[camNumber][i].x < 0 || prev_corners[camNumber][i].x > img_l.cols || prev_corners[camNumber][i].y < 0 || prev_corners[camNumber][i].y > img_l.rows || ((stereo == 2) && (right_corners[i].x < 0 || right_corners[i].x > img_l.cols || right_corners[i].y < 0 || right_corners[i].y > img_l.rows))) { status[i] = 0; } else { features_l[i] = prev_corners[camNumber][i]; if (stereo == 2) { features_r[i] = right_corners[i]; } status[i] = 1; } } else { if (status[i] == 1) // be careful not to overwrite 2s in updateVect status[i] = 0; } } } } img_l.copyTo(prev_img[camNumber]); // initialize new points if needed initMorePoints(img_l, img_r, status, features_l, features_r, stereo, camNumber); }
bool task3_5(const cv::Mat& image, const cv::Mat& orig) { cv::Mat grey, tmp, res; image.copyTo(grey); grey.convertTo(grey, CV_32F); grey.copyTo(res); res.convertTo(res, CV_8U); std::vector<cv::Mat> planes(2, cv::Mat()); std::vector<cv::Mat> polar(2, cv::Mat()); cv::dft(grey, tmp, cv::DFT_COMPLEX_OUTPUT); cv::split(tmp, planes); cv::cartToPolar(planes[0], planes[1], polar[0], polar[1]); int cx = polar[0].cols / 2; int cy = polar[0].rows / 2; cv::Point max; cv::Mat top = polar[0].rowRange(0, cx); cv::Mat bot = polar[0].rowRange(cx, polar[0].rows); int row = 0; do { cv::minMaxLoc(top.rowRange(row++, top.rows), 0, 0, 0, &max); } while (max.x == 0); int r = 3; cv::Mat noizeCol = polar[0].colRange(max.x - r, max.x + r); cv::Mat noizeRow = polar[0].rowRange(max.y - r, max.y + r); cv::Mat blurCol = polar[0].colRange(max.x - 12, max.x - 12 + 2 * r); cv::Mat blurRow = polar[0].rowRange(max.y - 3 * r, max.y - r); blurCol.copyTo(noizeCol); blurRow.copyTo(noizeRow); cv::Mat noizeColB = polar[0].colRange(polar[0].cols - max.x - r, polar[0].cols - max.x + r); cv::Mat noizeRowB = polar[0].rowRange(polar[0].rows - max.y - r, polar[0].rows - max.y + r); blurCol.copyTo(noizeColB); blurRow.copyTo(noizeRowB); cv::Mat roi = polar[0]; cv::Mat mean, stddev, tmp1; roi = roi.colRange(max.x + 20, roi.cols - max.x - 20).rowRange(max.y + 20, roi.cols - max.y - 20); for (int i = 0; i < roi.rows; ++i) { cv::Mat row = roi.row(i); cv::meanStdDev(row, mean, stddev); float m = mean.at<double>(0, 0); float st = stddev.at<double>(0, 0); for (Mfit mfit = row.begin<float>(); mfit != row.end<float>(); ++mfit) { if (*mfit > m + 1.5 * st) { *mfit = 0.5 * m; } } } visualization(polar[0], tmp); // // // cv::namedWindow("Lesson 2", CV_WINDOW_NORMAL); // cv::imshow("Lesson 2", tmp); // cv::waitKey(0); cv::polarToCart(polar[0], polar[1], planes[0], planes[1]); cv::merge(planes, tmp); cv::dft(tmp, tmp, cv::DFT_SCALE | cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT); tmp.convertTo(tmp, CV_8U); cv::Mat lut(1, 256, CV_32F, cv::Scalar(0)); for (int i = 0; i < 256; ++i) { lut.at<float>(0, i) = i; } for (int i = 65; i < 200; ++i) { lut.at<float>(0, i) = i - 30; } for (int i = 200; i < 220; ++i) { lut.at<float>(0, i) = i - 20; } lut.convertTo(lut, CV_8U); tmp.convertTo(tmp, CV_8U); cv::normalize(tmp, tmp, 0, 255, cv::NORM_MINMAX); cv::LUT(tmp, lut, tmp); cv::GaussianBlur(tmp, tmp, cv::Size(3, 3), 1); cv::medianBlur(tmp, tmp, 3); cv::Mat result; cv::matchTemplate(orig, tmp, result, CV_TM_SQDIFF); std::cout << "RMSE Task 3.5: " << result / (orig.cols * orig.rows) << std::endl; concatImages(res, tmp, res); cv::absdiff(tmp, orig, tmp); concatImages(res, tmp, res); cv::absdiff(image, orig, tmp); concatImages(res, tmp, res); concatImages(res, orig, res); // cv::namedWindow("Lesson 2", CV_WINDOW_NORMAL); // cv::imshow("Lesson 2", res); // cv::waitKey(0); return cv::imwrite(PATH + "Task3_5.jpg", res); }
cv::Mat DarkPixelFilter2Plugin::filter(const cv::Mat &data) const { cv::Mat out; if (data.channels() > 1) { // create gray image std::vector<cv::Mat> iChannels(data.channels()); cv::split(data, &iChannels[0]); double a = 1.0/iChannels.size(); iChannels[0].convertTo(out, CV_32F, a); for (int i=1; i<iChannels.size();i++) { out += a*iChannels[i]; } } else { if (data.depth() == CV_32F) { data.copyTo(out); } else { data.convertTo(out, CV_32F); } } // -) Compute mask from specified value: cv::Mat datamask; if (_maskByValue > -12345) { datamask = out != _maskByValue; } // -) Image -> 1/Image cv::divide(1.0,out,out,CV_32F); if (_verbose) { verboseDisplayImage("Image -> 1/Image", out); } emit progressValue(15); // -) Gaussian blur cv::GaussianBlur(out, out, cv::Size(_gbWinSize, _gbWinSize), _gbWinSize/1.5); if (_verbose) { verboseDisplayImage("Gaussian blur", out); } // -) Resize image int initW=out.cols, initH=out.rows; double rf = _resizeFactor; int newW = initW*rf; int newH = initH*rf; if (newW < 256 || newH < 256) { rf = qMax(256.0 / initW, 256.0 / initH); SD_TRACE1("New resize factor : %1", rf); } cv::resize(out, out, cv::Size(0, 0), rf, rf, cv::INTER_NEAREST); if (!datamask.empty()) { cv::resize(datamask, datamask, cv::Size(0, 0), rf, rf, cv::INTER_NEAREST); } emit progressValue(25); // -) Convert to 8U { double minVal, maxVal; cv::minMaxLoc(out, &minVal, &maxVal, 0, 0,datamask); cv::Scalar mean, std; cv::meanStdDev(out, mean, std, datamask); double nmin = mean.val[0] - 3.0*std.val[0]; minVal = (nmin < minVal) ? minVal : nmin; double nmax = mean.val[0] + 3.0*std.val[0]; maxVal = (nmax > maxVal) ? maxVal : nmax; cv::Mat out8U; out.convertTo(out8U, CV_8U, 255.0/(maxVal-minVal), -255.0*minVal/(maxVal-minVal)); out = out8U; emit progressValue(30); } // -) Median blur cv::medianBlur(out, out, 3); // -) Only bright objects { cv::Scalar mean = cv::mean(out, datamask); cv::threshold(out, out, mean[0], 255, cv::THRESH_TOZERO); cv::Mat mask, m = out == 0; m.convertTo(mask, out.type(), mean[0]/255.0); out = out + mask; } if (_verbose) { verboseDisplayImage("Only bright objects", out); } // -) Adaptive thresholding // Y = (Ymax - Ymin) * (X - Xmin)/(Xmax - Xmin) + Ymin // Y = (Ymin - Ymax) * (X - Xmin)/(Xmax - Xmin) + Ymax // transform sensivity [0.0 -> 1.0] into coeff [1.0 -> 0.3] double v = 1.0 - (0.7)*_sensivity; cv::Scalar mean = cv::mean(out, datamask); double c = -v*mean[0]; cv::adaptiveThreshold(out, out, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, _atWinSize, c); if (_verbose) { verboseDisplayImage("Adaptive thresholding", out); } emit progressValue(40); // -) Morpho close out = blurThreshClose(out, 3, 100, _mcWinSize, 2); if (_verbose) { verboseDisplayImage("Blur + Theshold + Morpho", out); } emit progressValue(50); // -) Resize to initial cv::resize(out, out, cv::Size(initW, initH), 0, 0, cv::INTER_LINEAR); emit progressValue(60); // -) Make contours smoother { int s = 7; cv::blur(out, out, cv::Size(s, s)); cv::Mat k1 = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(s, s)); cv::morphologyEx(out, out, cv::MORPH_ERODE, k1); } // -) Find contours std::vector<std::vector<cv::Point> > contours; cv::findContours(out, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); cv::Mat res(out.size(), CV_32F); res.setTo(_noDataValue); emit progressValue(80); if (contours.size() > 0) { double minArea = _minSize*_minSize; for (int i=0;i<contours.size();i++) { std::vector<cv::Point> contour = contours[i]; // remove line and points if (contour.size() < 3) continue; double s = cv::contourArea(contour); if (s > minArea) { cv::drawContours(res, contours, i, cv::Scalar::all(1.0), CV_FILLED); } } out = res; } else { _errorMessage = tr("No dark pixel zones found of size larger than %1").arg(_minSize); return cv::Mat(); } return out; }