Commit 9d04a0f8 authored by Neuberger Hajnalka's avatar Neuberger Hajnalka

OpenCV

parent 715cb2d2
REM "C:\lastools\bin\laszip.exe" -i "E:\Git\tutorial\als\als\rheine.xyz" -iparse xyz -odir "E:\Git\tutorial\als\als" -olas
REM "C:\lastools\bin\lasboundary.exe" -i "E:\Git\tutorial\als\als\rheine.las" -odir "E:\Git\tutorial\als\als" -okml -etrs89 -utm 32north -vertical_dhhn92
REM "C:\lastools\bin\las2dem.exe" -i "E:\Git\tutorial\als\als\rheine.las" -odir "E:\Git\tutorial\als\als" -opng -elevation -hillshade
REM "C:\lastools\bin\lastile.exe" -i "E:\Git\tutorial\als\als\rheine.las" -o "tile.laz" -tile_size 500 -faf -olas -odir "E:\Git\tutorial\als\als"
"C:\lastools\bin\las2dem.exe" -i "E:\Git\tutorial\als\als\*.las" -odir "E:\Git\tutorial\als\als" -opng -elevation -hillshade -etrs89 -utm 32north -vertical_dhhn92
REM "C:\lastools\bin\laszip.exe" -i ..\als\als\rheine.xyz -iparse xyz -odir ..\als\als -olas
REM "C:\lastools\bin\lasboundary.exe" -i "..\als\als\rheine.las" -odir "..\als\als" -okml -etrs89 -utm 32north -vertical_dhhn92
REM "C:\lastools\bin\las2dem.exe" -i "..\als\als\rheine.las" -odir "..\als\als" -opng -elevation -hillshade
REM "C:\lastools\bin\lastile.exe" -i "..\als\als\rheine.las" -o "tile.laz" -tile_size 500 -faf -olas -odir "..\als\als"
REM del "..\als\als\rheine.las"
REM "C:\lastools\bin\las2dem.exe" -i "..\als\als\*.las" -odir "..\als\als" -opng -elevation -hillshade -etrs89 -utm 32north -vertical_dhhn92
"C:\lastools\bin\las2dem.exe" -i "..\als\als\*.las" -odir "..\als\als" -otif -elevation -etrs89 -utm 32north -vertical_dhhn92 -odix "_dtm"
pause
\ No newline at end of file
......@@ -122,6 +122,16 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="parameters.cpp" />
<ClCompile Include="qualification.cpp" />
<ClCompile Include="riskmap.cpp" />
<ClCompile Include="steps.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="parameters.h" />
<ClInclude Include="qualification.hpp" />
<ClInclude Include="riskmap.hpp" />
<ClInclude Include="steps.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
......
......@@ -18,5 +18,31 @@
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="parameters.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="qualification.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="riskmap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="steps.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="parameters.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="qualification.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="riskmap.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="steps.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
#pragma once
#pragma once
#include <iostream>
#include <opencv2\opencv.hpp>
#include "parameters.h"
#include "qualification.hpp"
#include "riskmap.hpp"
#include "steps.h"
using namespace std;
using namespace cv;
int main() {
Mat src = cv::imread("tile_392500_5786500.png", cv::IMREAD_UNCHANGED);
if (!src.data) {
cout << "Could not find or open the image" << endl;
Mat dtm_32F = cv::imread("tile_392500_5786500_dtm.tif", cv::IMREAD_UNCHANGED);
Mat reference = cv::imread("reference.tif", cv::IMREAD_UNCHANGED);
Mat falsedtm = cv::imread("tile_392500_5786500.png", cv::IMREAD_UNCHANGED);
if (!dtm_32F.data) {
cout << "Could not find or open the dtm" << endl;
return -1;
}
if (!reference.data) {
cout << "Could not find or open the reference" << endl;
return -1;
}
if (!falsedtm.data) {
cout << "Could not find or open the falsedtm" << endl;
return -1;
}
imshow("DTM", src);
//imshow("DTM", falsedtm);
double breakvalue;
cv::Mat fdtm_32F = dtm_32F.clone();
cv::Mat bin;
cv::Mat filtered_32F = cv::Mat::ones(fdtm_32F.size(), CV_32F);
cv::Mat diff_32F = filtered_32F.clone();
cv::Mat kernel = cv::Mat::ones(3,3, CV_32F) / 9.0;
Mat cleaned1,cleaned2, final, detected, result_C3,closed, filled,opened;
cv::Mat mkernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
for (int j = 6; j <= 6; j = ++j) {
breakvalue = static_cast<double>(j / 100.0);
fdtm_32F = dtm_32F;
//Mean filter
for (int i = 1; i <= 9; ++i) {
filter2D(fdtm_32F, filtered_32F, CV_32F, kernel);
//Diff
diff_32F = filtered_32F - dtm_32F;
//Binary
threshold(diff_32F, bin, breakvalue, 255, 0);
if (bin.type() != CV_8U) {
bin.convertTo(bin, CV_8U);
}
smallcleanup(bin, cleaned1, 5);
bigcleanup(cleaned1, cleaned2, 100);
morphologyEx(cleaned2, closed, MORPH_CLOSE, mkernel, Point(-1, -1));
fill(closed, filled);
final = opened;
morphologyEx(filled, opened, MORPH_OPEN, mkernel, Point(-1, -1));
fdtm_32F = filtered_32F;
// Középpontok berajzolása
detected = final.clone();
if (reference.type() != CV_8U) {
reference.convertTo(reference, CV_8U);
}
if (detected.type() != CV_8U) {
detected.convertTo(detected, CV_8U);
}
vector<int> unique;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
vector<vector<Point>> contoursD;
vector<Vec4i> hierarchyD;
findContours(detected, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
vector<Moments> mu(contours.size());
vector<Point2f> mc(contours.size());
result_C3 = 255 - reference.clone();
cvtColor(result_C3, result_C3, COLOR_GRAY2BGR);
//Kráterek súlypontjának megtalálása és berajzolása különböző módokon
vector<int> ind(0);
for (int i = 0; i < contours.size(); ++i) {
mu[i] = moments(contours[i], false);
mc[i] = Point2d(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
circle(result_C3, mc[i], 3, Scalar(255, 0, 255), -1);
}
}
}
cv::imwrite("res.tif", result_C3);
waitKey();
return 0;
}
\ No newline at end of file
#pragma once
#include "parameters.h"
#include "qualification.hpp"
parameters::parameters() {}
void parameters::Print2File(std::ofstream& filename) {
filename << "resolution in cm: " << resolution << std::endl;
filename << "volume in cubem: " << volumeAboveLevel << " above " << Level << std::endl;
filename << "smallclean in pix: " << smallclean << std::endl;
filename << "maxdiameter in m: " << maxdiameter << std::endl;
filename << "maxpixel1in pix: " << maxpixels1 << std::endl;
filename << "closing: " << iter_closing << std::endl;
filename << "opeining: " << iter_opening << std::endl;
filename << "mindiameter in m: " << mindiameter << std::endl;
filename << "minpixel in pix: " << minpixels << std::endl;
filename << "maxpixel2 in pix: " << maxpixels2 << std::endl;
filename << "circularity: " << crc << std::endl;
filename << "dt: " << dt << std::endl;
filename << "xres: " << xres << std::endl;
filename << "yres: " << yres << std::endl;
}
void parameters::PrintConsole() {
std::cout << "resolution in cm: " << resolution << std::endl;
std::cout << "volume in cubem: " << volumeAboveLevel << " above " << Level << std::endl;
std::cout << "smallclean in pix: " << smallclean << std::endl;
std::cout << "maxdiameter in m: " << maxdiameter << std::endl;
std::cout << "maxpixel1 in pix: " << maxpixels1 << std::endl;
std::cout << "closing: " << iter_closing << std::endl;
std::cout << "opeining: " << iter_opening << std::endl;
std::cout << "mindiameter in m: " << mindiameter << std::endl;
std::cout << "minpixel in pix: " << minpixels << std::endl;
std::cout << "maxpixel2 in pix: " << maxpixels2 << std::endl;
std::cout << "circularity: " << crc << std::endl;
std::cout << "dt: " << dt << std::endl;
std::cout << "xres: " << xres << std::endl;
std::cout << "yres: " << yres << std::endl;
}
void parameters::ResolutionCheck(const cv::Mat& centers) {
if (yres <= 0) {
std::cout << "The yres cannot be a negative value or zero, enter a pozitive integer" << std::endl;
std::cin >> yres;
}
if (xres <= 0) {
std::cout << "The xres cannot be a negative value or zero, enter a pozitive integer" << std::endl;
std::cin >> xres;
}
if (yres > centers.rows) {
yres = centers.rows;
std::cout << "The riskmap vertical resolution too small, changed for: " << centers.rows << std::endl;
}
if (xres > centers.cols) {
xres = centers.cols;
std::cout << "The riskmap horizontal resolution too small, changed for: " << centers.cols << std::endl;
}
}
parameters::~parameters()
{
}
void parameters::CalcCurrentVales() {
smallclean = smallclean * 100.0 / float(resolution);
maxpixels1 = maxpixels1 * 100.0 / float(resolution);
dt = dt * 100.0 / float(resolution);
iter_closing = iter_closing * 100.0 / float(resolution);
iter_opening = iter_opening * 100.0 / float(resolution);
}
\ No newline at end of file
#pragma once
#include <iostream>
#include <opencv2\opencv.hpp>
#include <fstream>
class parameters
{
public:
int resolution = 100; //in cm
double mindiameter = 10; //in m
double maxdiameter = 16; //in m
int smallclean = 5; //in pix
int minsmooth = 1;
int maxsmooth = 30;
int minth = 1; //in cm
int maxth = 15; //in cm
int kernel_size = 3;
double crc = 0.37; //circle has the maximum value 0.08
double dt = 2.5; //
int skipped = 0;
int xres = 100; //riskmap horizontal resolution in m
int yres = 100; //riskmap vertical resolution in m
cv::Mat kernel = cv::Mat::ones(kernel_size, kernel_size, CV_32F) / 9.0;
cv::Mat mkernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
int minpixels = 35;
int maxpixels1 = 300;
int maxpixels2 = 303;
int smallpixels = 35;
int iter_closing = 1;
int iter_opening = 1;
double buff = 5;
double volumeAboveLevel = 0;
double Level = 0;
parameters();
void Print2File(std::ofstream& filename);
void PrintConsole();
void CalcCurrentVales();
void ResolutionCheck(const cv::Mat& centers);
~parameters();
};
\ No newline at end of file
#pragma once
#include <opencv2\opencv.hpp>
#include <vector>
#include "qualification.hpp"
#include <chrono>
using namespace std;
using namespace cv;
//Unique matrix creator
//http://stackoverflow.com/questions/24716932/obtaining-list-of-unique-pixel-values-in-opencv-mat
std::vector<int> Unique(const cv::Mat& input, bool sort){
if (input.type() != 0) {
std::cerr << "Unique function only works with CV_8U Mat" << std::endl;
return std::vector<int>();
}
std::vector<int> out;
for (int i = 0; i < input.rows; ++i) {
const uchar* row_ptr = input.ptr<uchar>(i);
for (int j = 0; j < input.cols; ++j){
int value = row_ptr[j];
if (std::find(out.begin(), out.end(), value) == out.end())
out.push_back(value);
}
}
if (sort)
std::sort(out.begin(), out.end());
return out;
}
//Összes középpontból kiválasztja azokat, ahol true pozitív találat van és ezeket megjelöli 128-as értékkel
int qualification(const Mat& craters, const Mat& centers, vector<int> unique, Mat& truecenters) {
//centers: 0 where nothing is, 255 where the centeres are
//craters: 255/65536 where nothing is, other ints where are craters, the int values mean the ID
//check the input Mats
truecenters = Mat::zeros(centers.size(), CV_8U);
if ((centers.rows != craters.rows) && (centers.cols != craters.cols)) {
cout << "The sizes of the input Mats in the qualification function are not the same" << endl;
return -1;
}
int s = static_cast<int>(unique.size()) - 1;
if (s < 0) {
s = 0;
}
int tp = 0;
for (int i = 0; i < centers.rows; i++) {
for (int j = 0; j < centers.cols; j++) {
if ((centers.at<uchar>(i, j) != 0) && (craters.at<uchar>(i, j) != unique[s])) {
for (int k = 0; k < unique.size(); ++k) {
if (unique[k] == craters.at<uchar>(i, j)) {
unique[k] = -1;
truecenters.at<uchar>(i, j) = 128;
++tp;
}
}
}
}
}
return tp;
}
int qualification(const Mat& craters, const Mat& centers, vector<int> unique) {
//centers: 0 where nothing is, 255 where the centeres are
//craters: 255/65536 where nothing is, other ints where are craters, the int values mean the ID
//check the input Mats
if ((centers.rows != craters.rows) && (centers.cols != craters.cols)) {
cout << "The sizes of the input Mats in the qualification function are not the same" << endl;
return -1;
}
int s = static_cast<int>(unique.size());
int tp = 0;
for (int i = 0; i < centers.rows; i++) {
for (int j = 0; j < centers.cols; j++) {
if ((centers.at<uchar>(i, j) != 0) && (craters.at<uchar>(i, j) != unique[s - 1])) {
for (int k = 0; k < unique.size(); k++) {
if (unique[k] == craters.at<uchar>(i, j)) {
unique[k] = -1;
tp++;
}
}
}
}
}
return tp;
}
#pragma once
#include <opencv2\opencv.hpp>
#include <vector>
#include <chrono>
using namespace std;
using namespace cv;
std::vector<int> Unique(const cv::Mat& input, bool sort);
int qualification(const Mat& craters, const Mat& centers, vector<int> unique, Mat& truecenters);
int qualification(const Mat& craters, const Mat& centers, vector<int> unique);
File added
#include <opencv2\opencv.hpp>
#include <iostream>
#include "qualification.hpp"
int CalculateColor(const cv::Mat& ColorMap, cv::Vec3b color) {
int area = 0;
for (int r = 0; r < ColorMap.rows; ++r) {
for (int c = 0; c < ColorMap.cols; ++c) {
if (ColorMap.at<cv::Vec3b>(r, c) == color) {
++area;
}
}
}
return area;
}
void riskmap(const cv::Mat& centers, const cv::Mat& falsedtm, cv::Mat& RiskMap, int xres, int yres, double buff, double tp, double fp, double& R, double& Y, double& G) {
//RiskMap is green by default: there is 0 crater
cv::Mat color(centers.size(), CV_8UC3, cv::Scalar(0, 0, 0));
//imshow("Riskmap", riskmap);
RiskMap = falsedtm.clone();
cv::cvtColor(RiskMap, RiskMap, COLOR_GRAY2RGB);
int bx = centers.cols;
int by = centers.rows;
int remainx = centers.cols % xres;
int remainy = centers.rows % yres;
if (remainx) {
bx = bx - (centers.cols % xres);
/*cv::Rect WhereRec(bx, 0, remainx, centers.rows);
if (cv::countNonZero(centers(WhereRec)) > 1) {
cv::Mat red(centers.rows, remainx, CV_8UC3, cv::Scalar(0, 0, 255));
red.copyTo(color(WhereRec));
}
else if (cv::countNonZero(centers(WhereRec)) == 1) {
cv::Mat yellow(centers.rows, remainx, CV_8UC3, cv::Scalar(0, 255, 255));
yellow.copyTo(color(WhereRec));
}*/
}
if (remainy) {
by = by - (centers.rows % yres);
/*cv::Rect WhereRec(0, by, centers.cols, remainy);
if (cv::countNonZero(centers(WhereRec)) > 1) {
cv::Mat red(remainy, centers.cols, CV_8UC3, cv::Scalar(0, 0, 255));
red.copyTo(color(WhereRec));
}
if (cv::countNonZero(centers(WhereRec)) == 1) {
cv::Mat yellow(remainy, centers.cols, CV_8UC3, cv::Scalar(0, 0, 255));
yellow.copyTo(color(WhereRec));
}*/
}
cv::Rect WhereRec(remainx / 2, remainy / 2, centers.cols - remainx, centers.rows - remainy);
cv::Mat green(centers.rows - remainy, centers.cols - remainx, CV_8UC3, cv::Scalar(0, 255, 0));
green.copyTo(color(WhereRec));
int num = 0;
for (int j = remainy / 2; j < by; j = j + yres) {
for (int i = remainx / 2; i < bx; i = i + xres) {
//Select the area, where I will count the craters
cv::Rect roi = cv::Rect(i, j, xres, yres);
cv::Mat imroi = centers(roi);
//rectangle(color, roi, 0);
//risk is the number of the centers
int risk = cv::countNonZero(imroi);
num += risk;
cv::Mat ROI = color(roi); //This is the selected area, which is a binary image
//If there is just one crater, the area will be yellow
if (risk == 1) {
for (int r = 0; r < imroi.rows; ++r) {
for (int c = 0; c < imroi.cols; ++c) {
if (imroi.at<uchar>(r, c) != 0) {
char side = 'o';
if (c - buff <= 0 && i - xres > 0) {
side = 'l'; //left
cv::Rect WhereRec(i - xres, j, xres, yres);
if (cv::countNonZero(centers(WhereRec)) <= 1) {
cv::Mat yellow(yres, xres, CV_8UC3, cv::Scalar(0, 255, 255));
yellow.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
}
else if ((xres - buff) <= c && (i + xres) < bx) {
side = 'r'; //right
cv::Rect WhereRec(i + xres, j, xres, yres);
if (cv::countNonZero(centers(WhereRec)) <= 1) {
cv::Mat yellow(yres, xres, CV_8UC3, cv::Scalar(0, 255, 255));
yellow.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
}
if (r - buff <= 0 && j - yres > 0) {
cv::Rect WhereRec(i, j - yres, xres, yres);
if (cv::countNonZero(centers(WhereRec)) <= 1) {
cv::Mat yellow(yres, xres, CV_8UC3, cv::Scalar(0, 255, 255));
yellow.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
if (side == 'l') {
cv::Rect WhereRec(i - xres, j - yres, xres, yres);
if (cv::countNonZero(centers(WhereRec)) <= 1) {
cv::Mat yellow(yres, xres, CV_8UC3, cv::Scalar(0, 255, 255));
yellow.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
}
else if (side == 'r') {
cv::Rect WhereRec(i + xres, j - yres, xres, yres);
if (cv::countNonZero(centers(WhereRec)) <= 1) {
cv::Mat yellow(yres, xres, CV_8UC3, cv::Scalar(0, 255, 255));
yellow.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
}
}
else if ((yres - buff) <= r && (j + yres) < by) {
cv::Rect WhereRec(i, j + yres, xres, yres);
if (cv::countNonZero(centers(WhereRec)) <= 1) {
cv::Mat yellow(yres, xres, CV_8UC3, cv::Scalar(0, 255, 255));
yellow.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
if (side == 'l') {
cv::Rect WhereRec(i - xres, j + yres, xres, yres);
if (cv::countNonZero(centers(WhereRec)) <= 1) {
cv::Mat yellow(xres, yres, CV_8UC3, cv::Scalar(0, 255, 255));
yellow.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
}
else if (side == 'r') {
cv::Rect WhereRec(i + xres, j + yres, xres, yres);
if (cv::countNonZero(centers(WhereRec)) <= 1) {
cv::Mat yellow(yres, xres, CV_8UC3, cv::Scalar(0, 255, 255));
yellow.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
}
}
}
}
}
cv::Mat yellow(yres, xres, CV_8UC3, cv::Scalar(0, 255, 255));
cv::Rect WhereRec(i, j, xres, yres);
yellow.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
//If there is more craters, the area will be red
if (risk > 1) {
//If an area red, the sourranding areas must be yellow, set these areas
int imin = remainx / 2;
int imax = i;
int jmin = remainy / 2;
int jmax = j;
if (i - xres >= 0) {
imin = i - xres;
}
if (i + xres < bx) {
imax = i + xres;
}
if (j - yres >= 0) {
jmin = j - yres;
}
if (j + yres < by) {
jmax = j + yres;
}
for (int yi = imin; yi <= imax; yi += xres) {
for (int yj = jmin; yj <= jmax; yj += yres) {
cv::Rect WhereRec(yi, yj, xres, yres);
if (cv::countNonZero(centers(WhereRec)) <= 1) {
cv::Mat yellow(yres, xres, CV_8UC3, cv::Scalar(0, 255, 255));
yellow.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
}
}
cv::Mat red(yres, xres, CV_8UC3, cv::Scalar(0, 0, 255));
cv::Rect WhereRec(i, j, xres, yres);
red.copyTo(color(WhereRec));
//rectangle(color, roi, 0);
}
}
}
//Put the colormap on the riskmap
int Empty = CalculateColor(color, cv::Vec3b(0, 0, 0));
int Red = CalculateColor(color, cv::Vec3b(0, 0, 255));
int Yellow = CalculateColor(color, cv::Vec3b(0, 255, 255));
int Green = CalculateColor(color, cv::Vec3b(0, 255, 0));
if (Red + Yellow + Green + Empty == color.rows * color.cols) {
//std::cout << "R: " << Red << " Y: " << Yellow << " G: " << Green << std::endl;
R = 1.0 * Red / (Red + Yellow + Green) * 100.0;
Y = 1.0 * Yellow / (Red + Yellow + Green) * 100.0;
G = 1.0 * Green / (Red + Yellow + Green) * 100.0;
}
double alpha = 0.3;
cv::addWeighted(color, alpha, RiskMap, 1.0 - alpha, 0.0, RiskMap);
}
void net(Mat& riskmap, int xres, int yres ) {
int bx = riskmap.cols;
int by = riskmap.rows;
int remainx = riskmap.cols % xres;
int remainy = riskmap.rows % yres;
if (remainx) {
bx = bx - (riskmap.cols % xres);
}
if (remainy) {
by = by - (riskmap.rows % yres);
}
for (int j = remainy / 2; j < by; j = j + yres) {
for (int i = remainx / 2; i < bx; i = i + xres) {
//Select the area, where I will count the craters
cv::Rect WhereRec = cv::Rect(i, j, xres, yres);
rectangle(riskmap, WhereRec, 0);
}
}
}
#pragma once
#include <opencv2\opencv.hpp>
int CalculateColor(const cv::Mat& Riskmap, cv::Vec3b color);
void riskmap(const cv::Mat& centers, const cv::Mat& falsedtm, cv::Mat& RiskMap, int xres, int yres, double buff, double tp, double fp, double& R, double& Y, double& G);
void net(Mat& riskmap, int xres, int yres);
#pragma once
#include "steps.h"
#include "qualification.hpp"
void smallcleanup(const cv::Mat& binary, cv::Mat& cleaned, int n) {
//std::cout << "Line1" << std::endl;
cleaned = binary.clone();
//std::cout << "Line2" << std::endl;
cv::Mat markers = cv::Mat::zeros(binary.size(), CV_8U);
//std::cout << "Line3" << std::endl;
std::vector<std::vector<cv::Point>> contours;
//std::cout << "Line4" << std::endl;
findContours(binary, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
//std::cout << "Line5 out of for" << std::endl;
for (size_t i = 0; i < contours.size(); ++i) {
//std::cout << "Line6 " << i << std::endl;
drawContours(markers, contours, static_cast<int>(i), 255, -1);
//std::cout << "Line7 " << i << std::endl;
if (countNonZero(markers) < n) {
//std::cout << "Line8 " << i << std::endl;
drawContours(cleaned, contours, static_cast<int>(i), 0, -1);
//std::cout << "Line9 " << i << std::endl;
}
//std::cout << "Line10 " << i << std::endl;
markers = cv::Mat::zeros(binary.size(), CV_8U);
//std::cout << "Line11 " << i << std::endl;
}
//std::cout << "Line12 of for" << std::endl;
}
void circularty(const cv::Mat& binary, cv::Mat& circ, double& crc) {
circ = binary.clone();
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
//cout << "Info: Area and Contour Length" << endl;
for (int i = 0; i < contours.size(); ++i){
double L = arcLength(contours[i], true);
if (!L) {
L = 1;
}
//cout << "contour: " << i << " areaopencv: " << contourArea(contours[i]) << " length: " << L << " circularity: " << contourArea(contours[i]) / (L * L) << endl;
double Q = (4 * CV_PI * (contourArea(contours[i]))) / (L * L);
//std::cout << Q << " " << (contourArea(contours[i])) / (L * L) << std::endl;
if (Q < crc) {
drawContours(circ, contours, i, 0, -1, 8, hierarchy, 0, cv::Point());
}
}
}
void bigcleanup(const cv::Mat& binary, cv::Mat& cleaned, int n) {
cleaned = binary.clone();
cv::Mat markers = cv::Mat::zeros(binary.size(), CV_8U);
std::vector<std::vector<cv::Point>> contours;
findContours(binary, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
for (size_t i = 0; i < contours.size(); ++i) {
drawContours(markers, contours, static_cast<int>(i), 255, -1);
if (countNonZero(markers) > n) {
drawContours(cleaned, contours, static_cast<int>(i), 0, -1);
}
markers = cv::Mat::zeros(binary.rows, binary.cols, CV_8U);
}
}
void fill(const cv::Mat& binary, cv::Mat& filled) {