图像修复之Exemplar-Based Inpainting
生活随笔
收集整理的這篇文章主要介紹了
图像修复之Exemplar-Based Inpainting
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原理參考 https://blog.csdn.net/frank_xu_0818/article/details/18842729
代碼參考 https://github.com/sooham/inpainting
- 本文簡單解讀下 Criminisi 等人論文"Region Filling and Object Removal by Exemplar-Based Inpainting.2004,TIP"中的基于紋理合成的圖像補全方法
- 該方法結合了"texture synthesis"(通過紋理樣圖生成大圖[1])與"inpainting"(基于微分方程填充圖像中的細縫[2]),很好地實現了大的目標物體的移除.
- 將圖像分為已知區域(source region)和待填充或移除區域(target region),移除從target region的邊界開始,以邊界點p為中心,設置塊的大小,形成塊(圖b),然后在已知區域中根據匹配準則找到相似的塊,如圖c以q’及q"為中心的兩個塊,最后選取最佳匹配的塊進行填充(圖d).
算法主要由計算優先級,搜索及復制三個部分組成:
1)優先級決定了移除順序,保證圖像中的線性結構傳播,目標邊界連通;
2)搜索即根據紋理相似距離(平方差距離和SSD)在已知區域中找到最佳匹配塊;
3)復制即將最佳匹配塊復制到對應的目標區域位置
優先級計算
代碼實現:
// 主函數 int main(int argc, char** argv) {// --------------- read filename strings ------------------std::string colorFilename, maskFilename;if (argc == 3) {colorFilename = argv[1];maskFilename = argv[2];} else {std::cerr << "Usage: ./inpainting colorImageFile maskImageFile" << std::endl;return -1;}// ---------------- read the images ------------------------// colorMat - color picture + border// maskMat - mask picture + border// grayMat - gray picture + bordercv::Mat colorMat, maskMat, grayMat;loadInpaintingImages(colorFilename,maskFilename,colorMat,maskMat,grayMat);// confidenceMat - confidence picture + bordercv::Mat confidenceMat;maskMat.convertTo(confidenceMat, CV_32F);confidenceMat /= 255.0f;// add borders around maskMat and confidenceMatcv::copyMakeBorder(maskMat, maskMat,RADIUS, RADIUS, RADIUS, RADIUS,cv::BORDER_CONSTANT, 255);cv::copyMakeBorder(confidenceMat, confidenceMat,RADIUS, RADIUS, RADIUS, RADIUS,cv::BORDER_CONSTANT, 0.0001f);// ---------------- start the algorithm -----------------contours_t contours; // mask contourshierarchy_t hierarchy; // contours hierarchy// priorityMat - priority values for all contour points + bordercv::Mat priorityMat(confidenceMat.size(),CV_32FC1); // priority value matrix for each contour pointassert(colorMat.size() == grayMat.size() &&colorMat.size() == confidenceMat.size() &&colorMat.size() == maskMat.size());cv::Point psiHatP; // psiHatP - point of highest confidencecv::Mat psiHatPColor; // color patch around psiHatPcv::Mat psiHatPConfidence; // confidence patch around psiHatPdouble confidence; // confidence of psiHatPConfidencecv::Point psiHatQ; // psiHatQ - point of closest patchcv::Mat result; // holds result from template matchingcv::Mat erodedMask; // eroded maskcv::Mat templateMask; // mask for template match (3 channel)// eroded mask is used to ensure that psiHatQ is not overlapping with targetcv::erode(maskMat, erodedMask, cv::Mat(), cv::Point(-1, -1), RADIUS);cv::Mat drawMat;// main loopconst size_t area = maskMat.total();while (cv::countNonZero(maskMat) != area) // end when target is filled{// set priority matrix to -.1, lower than 0 so that border area is never selectedpriorityMat.setTo(-0.1f);// get the contours of maskgetContours((maskMat == 0), contours, hierarchy);if (DEBUG) {drawMat = colorMat.clone();}// compute the priority for all contour pointscomputePriority(contours, grayMat, confidenceMat, priorityMat);// get the patch with the greatest priority 知道cv::minMaxLoc(priorityMat, NULL, NULL, NULL, &psiHatP);psiHatPColor = getPatch(colorMat, psiHatP);psiHatPConfidence = getPatch(confidenceMat, psiHatP);cv::Mat confInv = (psiHatPConfidence != 0.0f);confInv.convertTo(confInv, CV_32F);confInv /= 255.0f;// get the patch in source with least distance to psiHatPColor wrt source of psiHatPcv::Mat mergeArrays[3] = {confInv, confInv, confInv};cv::merge(mergeArrays, 3, templateMask);result = computeSSD(psiHatPColor, colorMat, templateMask);// set all target regions to 1.1, which is over the maximum value possilbe// from SSDresult.setTo(1.1f, erodedMask == 0);// get minimum point of SSD between psiHatPColor and colorMatcv::minMaxLoc(result, NULL, NULL, &psiHatQ);assert(psiHatQ != psiHatP);if (DEBUG) {cv::rectangle(drawMat, psiHatP - cv::Point(RADIUS, RADIUS), psiHatP + cv::Point(RADIUS+1, RADIUS+1), cv::Scalar(255, 0, 0));cv::rectangle(drawMat, psiHatQ - cv::Point(RADIUS, RADIUS), psiHatQ + cv::Point(RADIUS+1, RADIUS+1), cv::Scalar(0, 0, 255));showMat("red - psiHatQ", drawMat);}// updates// copy from psiHatQ to psiHatP for each colorspacetransferPatch(psiHatQ, psiHatP, grayMat, (maskMat == 0));transferPatch(psiHatQ, psiHatP, colorMat, (maskMat == 0));// fill in confidenceMat with confidences C(pixel) = C(psiHatP)confidence = computeConfidence(psiHatPConfidence);assert(0 <= confidence && confidence <= 1.0f);// update confidencepsiHatPConfidence.setTo(confidence, (psiHatPConfidence == 0.0f));// update maskMatmaskMat = (confidenceMat != 0.0f);}showMat("final result", colorMat, 0);return 0; }總結
以上是生活随笔為你收集整理的图像修复之Exemplar-Based Inpainting的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 百度传课网易云课堂在线教育平台竞品分析【
- 下一篇: 基层社会治理综合管理平台智慧街道Java