По просьбе @theodore в http://answers.opencv.org/question/86569/inpainting-depth-map-still-black-image-borders/?comment=86587#comment-86587 Я использовал образцы изображений, чтобы проверить поведение inpaint. Похоже, что он неправильно обрабатывает границу, поэтому можно создать границу с cv::copyMakeBorder
.
Вот расширенная версия с какой-то модульного тестирования:
int main(int argc, char* argv[])
{
cv::Mat input = cv::imread("C:/StackOverflow/Input/depthInpaint.png");
cv::Mat img;
cv::cvtColor(input, img, CV_BGR2GRAY);
cv::Mat inpainted;
const unsigned char noDepth = 0; // change to 255, if values no depth uses max value or use the mask image
//cv::inpaint(img, (img == noDepth), depth, 5.0, cv::INPAINT_TELEA); // img is the 8-bit input image (depth map with blank spots)
double inpaintRadius = 5;
int makeBorder = 1;
cv::Mat borderimg;
cv::copyMakeBorder(img, borderimg, makeBorder, makeBorder, makeBorder, makeBorder, cv::BORDER_REPLICATE);
cv::imshow("border", borderimg);
cv::inpaint(borderimg, (borderimg == noDepth), inpainted, inpaintRadius, cv::INPAINT_TELEA); // img is the 8-bit input image (depth map with blank spots)
cv::Mat originalEmbedded = borderimg(cv::Rect(makeBorder, makeBorder, img.cols, img.rows));
cv::Mat inpaintedEmbedded = inpainted(cv::Rect(makeBorder, makeBorder, img.cols, img.rows));
cv::Mat diffImage;
cv::absdiff(img, originalEmbedded, diffImage);
cv::imshow("embedding correct?", diffImage > 0);
cv::Mat mask = img == noDepth;
cv::imshow("mask", mask);
cv::imshow("input", input);
cv::imshow("inpainted", inpainted);
cv::imshow("inpainted from border", inpaintedEmbedded);
cv::waitKey(0);
return 0;
}
Вот сокращенный вариант, если вы считаете, что это правильно:
int main(int argc, char* argv[])
{
cv::Mat input = cv::imread("C:/StackOverflow/Input/depthInpaint.png");
cv::Mat img;
cv::cvtColor(input, img, CV_BGR2GRAY);
cv::Mat inpainted;
const unsigned char noDepth = 0; // change to 255, if values no depth uses max value or use the mask image
//cv::inpaint(img, (img == noDepth), depth, 5.0, cv::INPAINT_TELEA); // img is the 8-bit input image (depth map with blank spots)
double inpaintRadius = 5;
int makeBorderSize = 1;
cv::Mat borderimg;
//cv::copyMakeBorder(img, borderimg, borderSize, borderSize, borderSize, borderSize, cv::BORDER_REPLICATE);
cv::copyMakeBorder(img, borderimg, makeBorderSize, makeBorderSize, makeBorderSize, makeBorderSize, cv::BORDER_REPLICATE);
//cv::imshow("border", borderimg);
cv::inpaint(borderimg, (borderimg == noDepth), inpainted, inpaintRadius, cv::INPAINT_TELEA); // img is the 8-bit input image (depth map with blank spots)
// extract the original area without border:
cv::Mat inpaintedEmbedded = inpainted(cv::Rect(makeBorderSize, makeBorderSize, img.cols, img.rows));
cv::imshow("input", input);
cv::imshow("inpainted from border", inpaintedEmbedded);
cv::waitKey(0);
return 0;
}
Вот вход:
Вот вход с рамкой (borderiz е 5 визуализировать эффект лучше):
Вот результат:
вероятно значения на левой стороне не 255? можете ли вы добавить другое окно, которое отображает все значения глубины, равные 255 в глубине? например 'cv :: imshow (" newWindowName ", depthf == 255);' Если это причина, вы можете изменить использованную маску на '> 250' или что-то вместо' == 255' в строках 13 и 16 связанного кода , – Micka
Поскольку я получаю неизвестные значения глубины как 0, для меня это будет depthf == 0 или depthf> 5, но в любом случае вот несколько изображений: [Это] (https://drive.google.com/file/d/ 0B-qt8lafqDaeQy03QndSMkUxUkU/edit? Usp = sharing) показывает пример карты глубины. [Это] (https://drive.google.com/file/d/0B-qt8lafqDaeZUNOdVBNMlNLcXc/edit?usp=sharing) - это маска, используемая для inpainting. И [это] (https://drive.google.com/file/d/0B-qt8lafqDaeSi01cmJDc3Byc1U/edit?usp=sharing) является результатом.Любые идеи @ Мика? Левая граница как-то странная, но позволяет придерживаться верхней границы. Он явно включен в маску. – thomas
Вы посмотрели _tmp1 и _tmp? – Micka