Czasami, z różnych powodów, na obrazie pojawiają się wady, które możemy łatwo dostrzec. Wady takie, mogą przyczynić się do pogorszenia wyników (np. wykrycie nadmiarowych krawędzi). W OpenCV możemy takie wady usunąć (musimy jednak je określić...). Za wszystko odpowiedzialna jest funkcja cvInpaint.
void cvInpaint( const CvArr* src, const CvArr* inpaint_mask, CvArr* dst, double inpaintRange, int flags );
Obrazy wejsciowy i źródłowy muszą być tego samego typu i rozmiaru. Maska musi posiadać ten sam rozmiar co obraz, ponadto musi posiadać 8-bitową głębię i 1 kanał. inpaintRange określa w jakim promień obszaru przetwarzania dla danego piksela. Za duży może powodować uwzględnianie pikseli dosyć odległych i dla małych wad powodować rozmywanie obrazu. Flaga oznacza wybór metody. Są dwie do wyboru: CV_INPAINT_NS oraz CV_INPAINT_TELEA.
Poniższe obrazy przedstawiają obraz oryginalny, a dalej obrazy z wadą oraz obrazy o po naprawianiu i różnica pomiędzy obrazem oryginalnym i naprawionym. Jak będzie można zauważyć, dla małej wady wynik jest zadowalający. Dla większych, już nie jest tak dobrze. Niemniej, może być to pomocne, gdy chcemy usunać wadę wpływającą niekorzystnie na wynik programu.
Obraz oryginalny

Obraz z cienką krzywą
Obraz oryginalny

Po naprawie

Różnica

Obraz z grubą krzywą
Obraz oryginalny

Po naprawie

Różnica

Obraz z półprzezroczystą plamą
Obraz oryginalny

Po naprawie

Różnica

Przykład wykorzystania. Jest to program z poprzedniego wpisu (o myszce), tym razem rysujący większe punkty (okresla to zmienna promien). Po naciśnięciu klawisza "i", w miejscach zaznaczonych myszką, wykonany zostanie inpaintig. Z linii poleceń należy przekazać ścieżkę do pliku z obrazem.
bool wcisniety = false; CvScalar kolor; char* nazwa = "Rysowanie"; IplImage* maska; // maska okreslajaca piksele do zmiany double promien = 3.0; // promien rysowanych kolek void obsluga_myszki(int e, int x, int y, int fl, void* par) { IplImage * obraz = (IplImage*) par; // zmiany zapisujemy na obrazie i w masce switch (e) { case CV_EVENT_LBUTTONDOWN: cvCircle(obraz, cvPoint(x, y), promien, kolor, -1); cvCircle(maska, cvPoint(x, y), promien, kolor, -1); wcisniety = true; break; case CV_EVENT_LBUTTONUP: wcisniety = false; break; case CV_EVENT_MOUSEMOVE: if (wcisniety) { cvCircle(obraz, cvPoint(x, y), promien, kolor, -1); cvCircle(maska, cvPoint(x, y), promien, kolor, -1); } break; } } void inpaint(IplImage * obraz) { IplImage* naprawiony = cvCreateImage(cvGetSize(obraz), obraz->depth, obraz->nChannels); // funkcja naprawiajaca obraz cvInpaint(obraz, maska, naprawiony, 3, CV_INPAINT_TELEA); cvReleaseImage(&obraz); obraz = cvCloneImage(naprawiony); cvReleaseImage(&naprawiony); } void program_gl(char * sciezka) { cvNamedWindow(nazwa, CV_WINDOW_AUTOSIZE); IplImage* wys = cvLoadImage(sciezka, CV_LOAD_IMAGE_ANYCOLOR); // maska zawsze musi byc 8-bitowa i 1-kanalowa maska = cvCreateImage(cvGetSize(wys), 8, 1); cvZero(maska); kolor = cvScalarAll(1.0); cvSetMouseCallback(nazwa, obsluga_myszki, wys); while (true) { cvShowImage(nazwa, wys); int key = cvWaitKey(10); if (key == 'k') break; if (key == 'i') { inpaint(wys); cvZero(maska); } } cvReleaseImage(&wys); cvReleaseImage(&maska); cvDestroyWindow(nazwa); } /* * Inpainting * autor: ratixu.blogspot.com */ int main(int argc, char** argv) { program_gl(argv[1]); return (EXIT_SUCCESS); }