OpenCV_4.2.0/opencv_contrib-4.2.0/modules/ximgproc/samples/seeds.cpp

158 lines
4.2 KiB
C++

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/ximgproc.hpp>
#include <ctype.h>
#include <stdio.h>
#include <iostream>
using namespace cv;
using namespace cv::ximgproc;
using namespace std;
void trackbarChanged(int pos, void* data);
static void help()
{
cout << "\nThis program demonstrates SEEDS superpixels using OpenCV class SuperpixelSEEDS\n"
"Use [space] to toggle output mode\n"
"\n"
"It captures either from the camera of your choice: 0, 1, ... default 0\n"
"Or from an input image\n"
"Call:\n"
"./seeds [camera #, default 0]\n"
"./seeds [input image file]\n" << endl;
}
static const char* window_name = "SEEDS Superpixels";
static bool init = false;
void trackbarChanged(int, void*)
{
init = false;
}
int main(int argc, char** argv)
{
VideoCapture cap;
Mat input_image;
bool use_video_capture = false;
help();
if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])) )
{
cap.open(argc == 2 ? argv[1][0] - '0' : 0);
use_video_capture = true;
}
else if( argc >= 2 )
{
input_image = imread(argv[1]);
}
if( use_video_capture )
{
if( !cap.isOpened() )
{
cout << "Could not initialize capturing...\n";
return -1;
}
}
else if( input_image.empty() )
{
cout << "Could not open image...\n";
return -1;
}
namedWindow(window_name, 0);
int num_iterations = 4;
int prior = 2;
bool double_step = false;
int num_superpixels = 400;
int num_levels = 4;
int num_histogram_bins = 5;
createTrackbar("Number of Superpixels", window_name, &num_superpixels, 1000, trackbarChanged);
createTrackbar("Smoothing Prior", window_name, &prior, 5, trackbarChanged);
createTrackbar("Number of Levels", window_name, &num_levels, 10, trackbarChanged);
createTrackbar("Iterations", window_name, &num_iterations, 12, 0);
Mat result, mask;
Ptr<SuperpixelSEEDS> seeds;
int width, height;
int display_mode = 0;
for (;;)
{
Mat frame;
if( use_video_capture )
cap >> frame;
else
input_image.copyTo(frame);
if( frame.empty() )
break;
if( !init )
{
width = frame.size().width;
height = frame.size().height;
seeds = createSuperpixelSEEDS(width, height, frame.channels(), num_superpixels,
num_levels, prior, num_histogram_bins, double_step);
init = true;
}
Mat converted;
cvtColor(frame, converted, COLOR_BGR2HSV);
double t = (double) getTickCount();
seeds->iterate(converted, num_iterations);
result = frame;
t = ((double) getTickCount() - t) / getTickFrequency();
printf("SEEDS segmentation took %i ms with %3i superpixels\n",
(int) (t * 1000), seeds->getNumberOfSuperpixels());
/* retrieve the segmentation result */
Mat labels;
seeds->getLabels(labels);
/* get the contours for displaying */
seeds->getLabelContourMask(mask, false);
result.setTo(Scalar(0, 0, 255), mask);
/* display output */
switch (display_mode)
{
case 0: //superpixel contours
imshow(window_name, result);
break;
case 1: //mask
imshow(window_name, mask);
break;
case 2: //labels array
{
// use the last x bit to determine the color. Note that this does not
// guarantee that 2 neighboring superpixels have different colors.
const int num_label_bits = 2;
labels &= (1 << num_label_bits) - 1;
labels *= 1 << (16 - num_label_bits);
imshow(window_name, labels);
}
break;
}
int c = waitKey(1);
if( (c & 255) == 'q' || c == 'Q' || (c & 255) == 27 )
break;
else if( (c & 255) == ' ' )
display_mode = (display_mode + 1) % 3;
}
return 0;
}