Мы фактически работаем над проектом анализа изображений, где нам нужно идентифицировать объекты, которые исчезли/появились в сцене. Вот 2 изображения, один из которых был снят до того, как хирург и другие впоследствии сделали операцию.Оптический поток игнорирует разреженные движения
Во-первых, мы просто вычислили разницу между 2 изображения и вот результат (Обратите внимание, что я добавил 128 в результате Mat
просто иметь более хорошее изображение) :
цель состоит в том, чтобы обнаружить, что чашка (красная стрелка) исчезла из SCE ne и шприц (черная стрелка) вошли в сцену, другими словами, мы должны обнаружить ТОЛЬКО области, которые соответствуют объектам, оставленным/введенным в сцену. Кроме того, очевидно, что объекты в левом верхнем углу сцены немного сдвинулись с начальной позиции. Я думал о Optical flow
так что я использовал OpenCV C++
для расчета один на Farneback для того, чтобы увидеть, если это достаточно для нашего случая и вот результат мы получили, а затем код, который мы писали:
void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step, double, const Scalar& color)
{
cout << flow.channels() << "/" << flow.rows << "/" << flow.cols << endl;
for(int y = 0; y < cflowmap.rows; y += step)
for(int x = 0; x < cflowmap.cols; x += step)
{
const Point2f& fxy = flow.at<Point2f>(y, x);
line(cflowmap, Point(x,y), Point(cvRound(x+fxy.x), cvRound(y+fxy.y)), color);
circle(cflowmap, Point(x,y), 1, color, -1);
}
}
void MainProcessorTrackingObjects::diffBetweenImagesToTestTrackObject(string pathOfImageCaptured, string pathOfImagesAfterOneAction, string pathOfResultsFolder)
{
//Preprocessing step...
string pathOfImageBefore = StringUtils::concat(pathOfImageCaptured, imageCapturedFileName);
string pathOfImageAfter = StringUtils::concat(pathOfImagesAfterOneAction, *it);
Mat imageBefore = imread(pathOfImageBefore);
Mat imageAfter = imread(pathOfImageAfter);
Mat imageResult = (imageAfter - imageBefore) + 128;
// absdiff(imageAfter, imageBefore, imageResult);
string imageResultPath = StringUtils::stringFormat("%s%s-color.png",pathOfResultsFolder.c_str(), fileNameWithoutFrameIndex.c_str());
imwrite(imageResultPath, imageResult);
Mat imageBeforeGray, imageAfterGray;
cvtColor(imageBefore, imageBeforeGray, CV_RGB2GRAY);
cvtColor(imageAfter, imageAfterGray, CV_RGB2GRAY);
Mat imageResultGray = (imageAfterGray - imageBeforeGray) + 128;
// absdiff(imageAfterGray, imageBeforeGray, imageResultGray);
string imageResultGrayPath = StringUtils::stringFormat("%s%s-gray.png",pathOfResultsFolder.c_str(), fileNameWithoutFrameIndex.c_str());
imwrite(imageResultGrayPath, imageResultGray);
//*** Compute FarneBack optical flow
Mat opticalFlow;
calcOpticalFlowFarneback(imageBeforeGray, imageAfterGray, opticalFlow, 0.5, 3, 15, 3, 5, 1.2, 0);
drawOptFlowMap(opticalFlow, imageBefore, 5, 1.5, Scalar(0, 255, 255));
string flowPath = StringUtils::stringFormat("%s%s-flow.png",pathOfResultsFolder.c_str(), fileNameWithoutFrameIndex.c_str());
imwrite(flowPath, imageBefore);
break;
}
И знать, насколько точны этот оптический поток, я написал этот небольшой фрагмент кода, который вычисляет (IMAGEAFTER + FLOW) - IMAGEBEFORE:
//Reference method just to see the accuracy of the optical flow calculation
Mat accuracy = Mat::zeros(imageBeforeGray.rows, imageBeforeGray.cols, imageBeforeGray.type());
strinfor(int y = 0; y < imageAfter.rows; y ++)
for(int x = 0; x < imageAfter.cols; x ++)
{
Point2f& fxy = opticalFlow.at<Point2f>(y, x);
uchar intensityPointCalculated = imageAfterGray.at<uchar>(cvRound(y+fxy.y), cvRound(x+fxy.x));
uchar intensityPointBefore = imageBeforeGray.at<uchar>(y,x);
uchar intensityResult = ((intensityPointCalculated - intensityPointBefore)/2) + 128;
accuracy.at<uchar>(y, x) = intensityResult;
}
validationPixelBased = StringUtils::stringFormat("%s%s-validationPixelBased.png",pathOfResultsFolder.c_str(), fileNameWithoutFrameIndex.c_str());
imwrite(validationPixelBased, accuracy);
намерение, имеющих т его ((intensityPointCalculated - intensityPointBefore)/2) + 128;
просто для того, чтобы иметь приемлемое изображение.
IMAGE РЕЗУЛЬТАТ:
Поскольку он обнаруживает все регионы, которые были сдвинуты/Введенный/покинул сцену, мы считаем, что OpticalFlow
не достаточно, чтобы обнаружить только регионы, представляющие объекты исчезли/появился на сцене. Есть ли способ игнорировать разреженные движения, обнаруженные opticalFlow
? Или есть альтернативный способ обнаружить то, что нам нужно?
Я не в состоянии воспроизвести те же результаты .. можете ли вы рассказать мне значения, которые вы используете для этих констант: BLUR_SIZE, ERROR_THRESHOLD, MASK_THRESHOLD – Maystro
На основании входное изображение 960 x 540, у меня было BLUR_SIZE = 35, ERROR_THRESHOLD = 30, MASK_THRESHOLD = 1.5. Вы также можете настроить другие параметры, такие как разреженные уровни пирамиды оптического потока, размер патча и т. Д. Однако простое постоянное пороговое значение может не работать хорошо во всех ситуациях, и вы можете применить более сложные стратегии на основе ваших вариантов использования. – myin528
Спасибо за вашу поддержку. Ваш ответ не охватывает большинство моих дел, но я дам вам щедрость, так как он достаточно близко. – Maystro