diff --git a/FastROI/ConsoleApplication3/ConsoleApplication3.cpp b/FastROI/ConsoleApplication3/ConsoleApplication3.cpp index 160379c..4c66c5c 100644 --- a/FastROI/ConsoleApplication3/ConsoleApplication3.cpp +++ b/FastROI/ConsoleApplication3/ConsoleApplication3.cpp @@ -11,46 +11,47 @@ int main() cv::namedWindow("filter", cv::WINDOW_NORMAL); - cv::resizeWindow("binary", cv::Size(800, 600)); - cv::resizeWindow("result_image", cv::Size(800, 600)); - cv::resizeWindow("filter", cv::Size(800, 600)); + cv::resizeWindow("binary", cv::Size(500, 1000)); + cv::resizeWindow("result_image", cv::Size(500, 1000)); + cv::resizeWindow("filter", cv::Size(500, 1000)); - cv::VideoCapture cap("d://test_video.mp4"); + cv::VideoCapture cap("C://Github//FastROI//videos//test_video.mp4"); system("pause"); while (true) { + cv::Mat current_frame; if (cap.read(current_frame) == false) return 0; cv::Mat gray; - cv::cvtColor(current_frame, gray, cv::COLOR_BGR2GRAY); - cv::Mat binary; cv::threshold(gray, binary, 250, 255, cv::THRESH_BINARY + cv::THRESH_OTSU); - std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); - cv::Mat filter(cv::Size(binary.cols, binary.rows), CV_8UC1); memset(filter.data, 0, filter.cols * filter.rows); - //Blob Detection + + + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + + //Blob Detection fast::fastBlob blobDetector; blobDetector.compute(binary.data, binary.cols, binary.rows); auto blobs = blobDetector.blobInfo(); - //blobs = fast::fastBlob::rectFilter(blobs, 100, 200, 100, 200); - - + blobs = fast::fastBlob::rectFilter(blobs,50, 450, 50, 450); //Blob Detection + + std::vector colors = { cv::Scalar(255, 0, 0), cv::Scalar(0, 255, 0), cv::Scalar(0, 0, 255), cv::Scalar(255, 255, 0), cv::Scalar(0, 255, 255) }; + int count = 0; for (auto& blob : blobs) { fast::fastBlob::blobFill(filter.data, filter.cols, filter.rows, 255, blob); - cv::rectangle(current_frame, cv::Rect(blob.rectX(), blob.rectY(), blob.rectWidth(), blob.rectHeight()), cv::Scalar(0, 255, 0), 5); + cv::rectangle(current_frame, cv::Rect(blob.rectX(), blob.rectY(), blob.rectWidth(), blob.rectHeight()), colors[count % 5], 5); + count++; } - //Blob Detection - std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); diff --git a/FastROI/fastROI/fastBlob.cpp b/FastROI/fastROI/fastBlob.cpp index cf303d6..809f501 100644 --- a/FastROI/fastROI/fastBlob.cpp +++ b/FastROI/fastROI/fastBlob.cpp @@ -206,12 +206,12 @@ namespace fast { if (min_x > point.col) min_x = point.col; - else if (max_x <= point.col) + if (max_x < point.col) max_x = point.col; if (min_y > point.row) min_y = point.row; - else if (max_y <= point.row) + if (max_y < point.row) max_y = point.row; centeroid_x += ((double)point.col / count); @@ -221,8 +221,8 @@ namespace fast { calPoint.y = point.row; features.push_back(calPoint); } - int width = max_x - min_x; - int height = max_y - min_y; + int width = max_x - min_x + 1; + int height = max_y - min_y + 1; @@ -505,117 +505,106 @@ void fast::fastBlob::blobFill(unsigned char* buffer, int width, int height, unsi HVERROR(error, "Invalid blob info"); } - int start_y = info.rectY(); - int end_Y = info.rectHeight() + info.rectY(); + int size = info.rectHeight() * info.rectWidth(); + int blobWidth = info.rectWidth(); + int blobHeight = info.rectHeight(); + int blobStartX = info.rectX(); + int blobStartY = info.rectY(); + std::shared_ptr marker(new unsigned char[size], [](unsigned char* ptr) { + delete[] ptr; + }); + std::memset(marker.get(), 0, sizeof(unsigned char) * size); + auto marker_buffer = marker.get(); - //first line drawing and temp_top fill - std::vector temp_top; - for (auto& element : points) { - if (element.y == start_y) { - temp_top.push_back(element); - buffer[(int)element.y * width + (int)element.x] = pixel; - } - + + for (auto& point : points) { + int x = (int)point.x - blobStartX; + int y = (int)point.y - blobStartY; + marker_buffer[y * blobWidth + x] = 255; } - //first line drawing and temp_top fill - - for (int row = start_y+1; row < end_Y + 1; row++) { + std::deque stack; + for (int x = 0; x < blobWidth; x++) { + fast::calPoint point1; + fast::calPoint point2; - std::deque columns; - for (auto& element : points) { - if (element.y == row) - columns.push_back(element); - } - - - - - if (columns.size() == 0) continue; + point1.x = x; + point1.y = blobHeight - 1; + point2.x = x; + point2.y = 0; - - - - std::sort(columns.begin(), columns.end(), [&](fast::calPoint & first, fast::calPoint& second) { - return first.x < second.x; - }); + stack.push_back(point1); + stack.push_back(point2); + } - - - - - std::vector current_top = temp_top; - temp_top.clear(); + for (int y = 0; y < blobHeight; y++) { + fast::calPoint point1; + fast::calPoint point2; - - - - - std::deque active_columns; - while (!columns.empty()) { - auto current_element = columns.front(); - columns.pop_front(); + point1.x = blobWidth - 1; + point1.y = y; - //std::cout << "current x :" << current_element.x << std::endl; - //std::cout << "current y :" << current_element.y << std::endl; + point2.x = 0; + point2.y = y; - int start_dy = current_element.y - 1; - int end_dy = current_element.y + 1; - int start_dx = current_element.x - 1; - int end_dx = current_element.x + 1; + stack.push_back(point1); + stack.push_back(point2); + } + while (!stack.empty()) { - bool found = false; - for (auto& top_element : current_top) { - for (int dy = start_dy; dy <= end_dy && found == false; dy++) { - for (int dx = start_dx; dx<= end_dx && found == false; dx++) { - + auto current_position = stack.back(); + stack.pop_back(); - //std::cout << "dx :" << dx << std::endl; - //std::cout << "dy :" << dy << std::endl; + int current_index = (int)current_position.y * blobWidth + (int)current_position.x; - if (top_element.x == dx && top_element.y == dy) - found = true; - } - } - } - - if (found) { - active_columns.push_back(current_element); - } - else { - buffer[(int)current_element.y * width + (int)current_element.x] = pixel; - } - temp_top.push_back(current_element); - } + if (marker_buffer[current_index] != 0) + continue; - //std::cout << "active line check done" << std::endl; + marker_buffer[current_index] = 1; - if (active_columns.size() == 0) { - //std::cout << "something wrong!!!" << std::endl; - //std::cout << "current size = " << active_columns.size() << std::endl; - continue; + if (current_position.x - 1 >= 0) { + fast::calPoint temp; + temp.x = current_position.x - 1; + temp.y = current_position.y; + stack.push_back(temp); } - //std::cout << "drawing start" << std::endl; - //std::cout << "current active line count = " << active_columns.size() << std::endl; + if (current_position.x + 1 < blobWidth) { + fast::calPoint temp; + temp.x = current_position.x + 1; + temp.y = current_position.y; + stack.push_back(temp); + } - std::sort(active_columns.begin(), active_columns.end(), [&](fast::calPoint& first, fast::calPoint& second) { - return first.x < second.x; - }); + if (current_position.y - 1 >= 0) { + fast::calPoint temp; + temp.x = current_position.x; + temp.y = current_position.y - 1; + stack.push_back(temp); + } + if (current_position.y + 1 < blobHeight) { + fast::calPoint temp; + temp.x = current_position.x; + temp.y = current_position.y + 1; + stack.push_back(temp); + } + } - fast::calPoint first_element = active_columns.front(); - fast::calPoint second_element = active_columns.back(); - for (int x = first_element.x; x <= second_element.x; x++) - buffer[(int)row * width + (int)x] = pixel; + for (int y = 0; y < blobHeight; y++) { + for (int x = 0; x < blobWidth; x++) { + int marker_index = blobWidth * y + x; + int buffer_index = width * (y + blobStartY) + (x + blobStartX); + if (marker_buffer[marker_index] == 0 || marker_buffer[marker_index] == 255) + buffer[buffer_index] = pixel; + } } - } \ No newline at end of file diff --git a/FastROI/lib/Debug/blobInfo.h b/FastROI/lib/Debug/blobInfo.h index 4031efc..e9379cb 100644 --- a/FastROI/lib/Debug/blobInfo.h +++ b/FastROI/lib/Debug/blobInfo.h @@ -54,6 +54,11 @@ namespace fast { void setBlobPoints(std::vector& points) { this->_blob_points = points; } + + std::vector getBlobPoints() { + return this->_blob_points; + } + }; } diff --git a/FastROI/lib/Debug/fastBlob.h b/FastROI/lib/Debug/fastBlob.h index 74e41d1..3fd5a5e 100644 --- a/FastROI/lib/Debug/fastBlob.h +++ b/FastROI/lib/Debug/fastBlob.h @@ -26,11 +26,10 @@ namespace fast { void compute(unsigned char * buffer, int width, int height); std::vector blobInfo(); - std::vector rectFilter(int minWidth, int maxWidth, int minHeight, int maxHeight); - - + static std::vector rectFilter(std::vector blobInfo, int minWidth, int maxWidth, int minHeight, int maxHeight); + static void blobFill(unsigned char* buffer, int width, int height , unsigned char pixel, fast::blobInfo info); }; } diff --git a/FastROI/lib/Debug/fastROI.dll b/FastROI/lib/Debug/fastROI.dll index 52c7c6e..d903b6a 100644 Binary files a/FastROI/lib/Debug/fastROI.dll and b/FastROI/lib/Debug/fastROI.dll differ diff --git a/FastROI/lib/Debug/fastROI.lib b/FastROI/lib/Debug/fastROI.lib index e1d73f7..cb8759a 100644 Binary files a/FastROI/lib/Debug/fastROI.lib and b/FastROI/lib/Debug/fastROI.lib differ diff --git a/FastROI/lib/Release/blobInfo.h b/FastROI/lib/Release/blobInfo.h index 4031efc..e9379cb 100644 --- a/FastROI/lib/Release/blobInfo.h +++ b/FastROI/lib/Release/blobInfo.h @@ -54,6 +54,11 @@ namespace fast { void setBlobPoints(std::vector& points) { this->_blob_points = points; } + + std::vector getBlobPoints() { + return this->_blob_points; + } + }; } diff --git a/FastROI/lib/Release/fastBlob.h b/FastROI/lib/Release/fastBlob.h index 74e41d1..3fd5a5e 100644 --- a/FastROI/lib/Release/fastBlob.h +++ b/FastROI/lib/Release/fastBlob.h @@ -26,11 +26,10 @@ namespace fast { void compute(unsigned char * buffer, int width, int height); std::vector blobInfo(); - std::vector rectFilter(int minWidth, int maxWidth, int minHeight, int maxHeight); - - + static std::vector rectFilter(std::vector blobInfo, int minWidth, int maxWidth, int minHeight, int maxHeight); + static void blobFill(unsigned char* buffer, int width, int height , unsigned char pixel, fast::blobInfo info); }; } diff --git a/FastROI/lib/Release/fastROI.dll b/FastROI/lib/Release/fastROI.dll index 741f3a3..a550443 100644 Binary files a/FastROI/lib/Release/fastROI.dll and b/FastROI/lib/Release/fastROI.dll differ diff --git a/FastROI/lib/Release/fastROI.lib b/FastROI/lib/Release/fastROI.lib index 1594236..4fb8983 100644 Binary files a/FastROI/lib/Release/fastROI.lib and b/FastROI/lib/Release/fastROI.lib differ diff --git a/images/blobFilter.gif b/images/blobFilter.gif new file mode 100644 index 0000000..c9dc3ac Binary files /dev/null and b/images/blobFilter.gif differ