Привет, я в настоящее время пишу простое приложение на C ++, использующее библиотеку OpenCV, чтобы сегментировать тему изображения на фоне. Приложение считывает файл изображения и использует алгоритм водораздела для создания маски на основе данных, которые он находит по краям, и данных, которые он находит в центре изображения.
(Для начала я создал объект изображения с общим значением -1. Затем я создал рамку вокруг пустого изображения со значением 1. Затем я создал прямоугольник примерно в центре изображения, который имеет значение 2. Граница и прямоугольник не соприкасаются.)
Я пытаюсь удалить данные из изображения, используя сгенерированную маску, используя побитовое И между исходным изображением и автоматически сгенерированной маской.
Я написал это на C ++ и был бы очень признателен, если бы кто-нибудь взглянул на мой код. Единственный похожий пример, который я смог найти, — это использование нативных привязок OpenCV для Python.
Образец Маски: http://i.imgur.com/a0SUwy3.png
Образец изображения: http://i.imgur.com/FQywu6P.png
// Usage: ./app input.jpg
#include "opencv2/opencv.hpp"#include <string>
using namespace cv;
using namespace std;
class WatershedSegmenter{
private:
cv::Mat markers;
public:
void setMarkers(cv::Mat& markerImage)
{
markerImage.convertTo(markers, CV_32S);
}
cv::Mat process(cv::Mat &image)
{
cv::watershed(image, markers);
markers.convertTo(markers,CV_8U);
return markers;
}
};int main(int argc, char* argv[])
{
cv::Mat image = cv::imread(argv[1]);
cv::Mat blank(image.size(),CV_8U,cv::Scalar(0xFF));
cv::Mat dest(image.size(),CV_8U,cv::Scalar(0xFF));
imshow("originalimage", image);
// Create markers image
cv::Mat markers(image.size(),CV_8U,cv::Scalar(-1));
//Rect(topleftcornerX, topleftcornerY, width, height);
//top rectangle
markers(Rect(0,0,image.cols, 5)) = Scalar::all(1);
//bottom rectangle
markers(Rect(0,image.cols-5,image.cols, 5)) = Scalar::all(1);
//left rectangle
markers(Rect(0,0,5,image.rows)) = Scalar::all(1);
//right rectangle
markers(Rect(image.cols-5,0,5,image.rows)) = Scalar::all(1);
//centre rectangle
markers(Rect(image.cols/2,image.rows/2,50, 50)) = Scalar::all(2);//Create watershed segmentation object
WatershedSegmenter segmenter;
segmenter.setMarkers(markers);
cv::Mat result = segmenter.process(image);
result.convertTo(result,CV_8U);
bitwise_and(image, blank, dest, result);
imshow("final_result", dest);
cv::waitKey(0);
return 0;
}
Работай!
// Usage: ./app input.jpg
#include "opencv2/opencv.hpp"#include <string>
using namespace cv;
using namespace std;
class WatershedSegmenter{
private:
cv::Mat markers;
public:
void setMarkers(cv::Mat& markerImage)
{
markerImage.convertTo(markers, CV_32S);
}
cv::Mat process(cv::Mat &image)
{
cv::watershed(image, markers);
markers.convertTo(markers,CV_8U);
return markers;
}
};int main(int argc, char* argv[])
{
cv::Mat image = cv::imread(argv[1]);
cv::Mat blank(image.size(),CV_8U,cv::Scalar(0xFF));
cv::Mat dest;
imshow("originalimage", image);
// Create markers image
cv::Mat markers(image.size(),CV_8U,cv::Scalar(-1));
//Rect(topleftcornerX, topleftcornerY, width, height);
//top rectangle
markers(Rect(0,0,image.cols, 5)) = Scalar::all(1);
//bottom rectangle
markers(Rect(0,image.rows-5,image.cols, 5)) = Scalar::all(1);
//left rectangle
markers(Rect(0,0,5,image.rows)) = Scalar::all(1);
//right rectangle
markers(Rect(image.cols-5,0,5,image.rows)) = Scalar::all(1);
//centre rectangle
int centreW = image.cols/4;
int centreH = image.rows/4;
markers(Rect((image.cols/2)-(centreW/2),(image.rows/2)-(centreH/2), centreW, centreH)) = Scalar::all(2);
markers.convertTo(markers,CV_BGR2GRAY);
imshow("markers", markers);
//Create watershed segmentation object
WatershedSegmenter segmenter;
segmenter.setMarkers(markers);
cv::Mat wshedMask = segmenter.process(image);
cv::Mat mask;
convertScaleAbs(wshedMask, mask, 1, 0);
double thresh = threshold(mask, mask, 1, 255, THRESH_BINARY);
bitwise_and(image, image, dest, mask);
dest.convertTo(dest,CV_8U);
imshow("final_result", dest);
cv::waitKey(0);
return 0;
}
Других решений пока нет …