You can use findContours
and drawContours
for this task. Here's a tutorial from OpenCV
findContours
will store the ordered sequence of points for each contour in a std::vector<std::vector<cv::Point>>
. You can rebuild the original contour using drawContour
.
Or you can collect all the non-zero points in your image with findNonZero
, saving points in a std::vector<cv::Point>
. You can then set all those points to rebuilt your original image.
Have a look at both methods in the following code:
#include <opencv2/opencv.hpp>
using namespace cv;
int main(int, char**)
{
// Load grayscale image
Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
// Get all contours in the image
vector<vector<Point>> contours;
findContours(img.clone(), contours, CV_RETR_LIST, CHAIN_APPROX_NONE);
// Draw all contours in green on a black image
Mat3b rec(img.rows, img.cols, Vec3b(0,0,0));
drawContours(rec, contours, -1, Scalar(0,255,0), 1);
imshow("Original", img);
imshow("Reconstructed", rec);
waitKey();
// Save all non-zero pixel positions
vector<Point> pts;
findNonZero(img, pts);
// Set the pixels to red, according to the points in pts
Mat3b rec2(img.rows, img.cols, Vec3b(0, 0, 0));
for (int i = 0; i < pts.size(); ++i)
{
rec2(pts[i]) = Vec3b(0,0,255);
}
imshow("Reconstructed 2", rec2);
waitKey();
return 0;
}