Skip to content

Commit 76263a3

Browse files
authored
Merge pull request spmallick#293 from krutikabapat/master
Added Image Inpainting Code
2 parents 5ae27a4 + e0624f6 commit 76263a3

12 files changed

+381
-0
lines changed

Image-Inpainting/CMakeLists.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
cmake_minimum_required(VERSION 2.8.12)
2+
3+
PROJECT(inpainting)
4+
SET(OpenCV_DIR /home/hp/workfolder/OpenCV-Installation/installation/OpenCV-master/lib/cmake/opencv4)
5+
6+
######################## EDIT IF REQUIRED ####################
7+
# ###Uncomment the line below and specify the path to OpenCV directory i.e. the path to the OpenCVConfig.cmake file. Check the examples given below.
8+
#SET(OpenCV_DIR Enter-the-path-of-OpenCV-installation-on-your-system)
9+
10+
11+
################### OpenCV_DIR Examples #####################
12+
13+
### MACOS : /usr/local/Cellar/opencv/3.3.1_1/share/OpenCV/
14+
15+
### UBUNTU : /usr/local/share/OpenCV/
16+
17+
### WINDOWS : C:\Users\yourname\Documents\opencv-3.3.1\build\install
18+
19+
##############################################################
20+
21+
22+
23+
24+
################### ***DO NOT EDIT*** #####################
25+
26+
############# Common Instructions for all Users ############
27+
find_package( OpenCV REQUIRED )
28+
29+
include_directories( ${OpenCV_INCLUDE_DIRS})
30+
31+
MACRO(add_example name)
32+
ADD_EXECUTABLE(${name} ${name}.cpp)
33+
TARGET_LINK_LIBRARIES(${name} ${OpenCV_LIBS} )
34+
ENDMACRO()
35+
36+
add_example(inpaint)

Image-Inpainting/FMM-eye.png

15.2 MB
Loading

Image-Inpainting/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 vishwesh5
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Image-Inpainting/LearnOpenCV.com.png

20.1 KB
Loading

Image-Inpainting/NS-eye.png

15 MB
Loading

Image-Inpainting/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Image Inpainting
2+
3+
4+
## Usage
5+
6+
### Python
7+
8+
```
9+
python3 inpaint.py sample.jpeg
10+
```
11+
12+
### C++
13+
14+
```
15+
g++ inpaint.cpp `pkg-config opencv --cflags --libs` -o inpaint
16+
./inpaint sample.jpeg
17+
```
18+
You can also **cmake** as follows:
19+
20+
```
21+
mkdir build && cd build
22+
cmake ..
23+
cmake --build . --config Release
24+
```
25+
26+
The built code can then be used as follows:
27+
28+
```
29+
./build/inpaint sample.jpeg
30+
```
31+
32+
## Performance Comparison
33+
34+
```
35+
Time: FMM = 194445.94073295593 ms
36+
Time: NS = 179731.82344436646 ms
37+
```

Image-Inpainting/eye.jpg

1.9 MB
Loading

Image-Inpainting/inpaint-time.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import numpy as np
2+
import cv2 as cv
3+
import sys
4+
import time
5+
6+
# OpenCV Utility Class for Mouse Handling
7+
class Sketcher:
8+
def __init__(self, windowname, dests, colors_func):
9+
self.prev_pt = None
10+
self.windowname = windowname
11+
self.dests = dests
12+
self.colors_func = colors_func
13+
self.dirty = False
14+
cv.namedWindow(self.windowname, cv.WINDOW_NORMAL)
15+
cv.namedWindow(self.windowname+": mask", cv.WINDOW_NORMAL)
16+
self.show()
17+
cv.setMouseCallback(self.windowname, self.on_mouse)
18+
19+
def show(self):
20+
cv.imshow(self.windowname, self.dests[0])
21+
cv.imshow(self.windowname + ": mask", self.dests[1])
22+
23+
# onMouse function for Mouse Handling
24+
def on_mouse(self, event, x, y, flags, param):
25+
pt = (x, y)
26+
if event == cv.EVENT_LBUTTONDOWN:
27+
self.prev_pt = pt
28+
elif event == cv.EVENT_LBUTTONUP:
29+
self.prev_pt = None
30+
31+
if self.prev_pt and flags & cv.EVENT_FLAG_LBUTTON:
32+
for dst, color in zip(self.dests, self.colors_func()):
33+
cv.line(dst, self.prev_pt, pt, color, 5)
34+
self.dirty = True
35+
self.prev_pt = pt
36+
self.show()
37+
38+
39+
def main():
40+
41+
print("Usage: python inpaint <image_path>")
42+
print("Keys: ")
43+
print("t - inpaint using FMM")
44+
print("n - inpaint using NS technique")
45+
print("r - reset the inpainting mask")
46+
print("ESC - exit")
47+
48+
# Read image in color mode
49+
img = cv.imread(sys.argv[1], cv.IMREAD_COLOR)
50+
inpaintMask = cv.imread(sys.argv[2],cv.IMREAD_GRAYSCALE)
51+
52+
# If image is not read properly, return error
53+
if img is None:
54+
print('Failed to load image file: {}'.format(args["image"]))
55+
return
56+
57+
# Create a copy of original image
58+
img_mask = img.copy()
59+
60+
# Create a black copy of original image
61+
# Acts as a mask
62+
inpaintMask = cv.resize(inpaintMask,(img.shape[1],img.shape[0]))#np.zeros(img.shape[:2], np.uint8)
63+
64+
# Create sketch using OpenCV Utility Class: Sketcher
65+
sketch = Sketcher('image', [img_mask, inpaintMask], lambda : ((255, 255, 255), 255))
66+
cv.namedWindow('Inpaint Output using NS Technique', cv.WINDOW_NORMAL)
67+
cv.namedWindow('Inpaint Output using FMM', cv.WINDOW_NORMAL)
68+
69+
while True:
70+
ch = cv.waitKey()
71+
if ch == 27:
72+
break
73+
if ch == ord('t'):
74+
75+
# Use Algorithm proposed by Alexendra Telea: Fast Marching Method (2004)
76+
# Reference: https://pdfs.semanticscholar.org/622d/5f432e515da69f8f220fb92b17c8426d0427.pdf
77+
t1 = time.time()
78+
res = cv.inpaint(src=img_mask, inpaintMask=inpaintMask, inpaintRadius=30, flags=cv.INPAINT_TELEA)
79+
t2 = time.time()
80+
print("Time: FMM = {} ms".format((t2-t1)*1000))
81+
82+
#cv.namedWindow('Inpaint Output using FMM', cv.NORMAL_WINDOW)
83+
cv.imshow('Inpaint Output using FMM', res)
84+
cv.imwrite("FMM-eye.png",res)
85+
if ch == ord('n'):
86+
87+
# Use Algorithm proposed by Bertalmio, Marcelo, Andrea L. Bertozzi, and Guillermo Sapiro: Navier-Stokes, Fluid Dynamics, and Image and Video Inpainting (2001)
88+
t1 = time.time()
89+
res = cv.inpaint(src=img_mask, inpaintMask=inpaintMask, inpaintRadius=30, flags=cv.INPAINT_NS)
90+
t2 = time.time()
91+
print("Time: NS = {} ms".format((t2-t1)*1000))
92+
93+
#cv.namedWindow('Inpaint Output using NS Technique', cv.WINDOW_NORMAL)
94+
cv.imshow('Inpaint Output using NS Technique', res)
95+
cv.imwrite("NS-eye.png",res)
96+
if ch == ord('r'):
97+
img_mask[:] = img
98+
inpaintMask[:] = 0
99+
sketch.show()
100+
101+
print('Completed')
102+
103+
104+
if __name__ == '__main__':
105+
main()
106+
cv.destroyAllWindows()

Image-Inpainting/inpaint.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#include "opencv2/imgcodecs.hpp"
2+
#include "opencv2/highgui.hpp"
3+
#include "opencv2/imgproc.hpp"
4+
#include "opencv2/photo.hpp"
5+
6+
#include <iostream>
7+
8+
using namespace cv;
9+
using namespace std;
10+
11+
// Declare Mat objects for original image and mask for inpainting
12+
Mat img, inpaintMask;
13+
// Mat object for result output
14+
Mat res;
15+
Point prevPt(-1,-1);
16+
17+
// onMouse function for Mouse Handling
18+
// Used to draw regions required to inpaint
19+
static void onMouse( int event, int x, int y, int flags, void* )
20+
{
21+
if( event == EVENT_LBUTTONUP || !(flags & EVENT_FLAG_LBUTTON) )
22+
prevPt = Point(-1,-1);
23+
else if( event == EVENT_LBUTTONDOWN )
24+
prevPt = Point(x,y);
25+
else if( event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON) )
26+
{
27+
Point pt(x,y);
28+
if( prevPt.x < 0 )
29+
prevPt = pt;
30+
line( inpaintMask, prevPt, pt, Scalar::all(255), 5, 8, 0 );
31+
line( img, prevPt, pt, Scalar::all(255), 5, 8, 0 );
32+
prevPt = pt;
33+
imshow("image", img);
34+
imshow("image: mask", inpaintMask);
35+
}
36+
}
37+
38+
39+
int main( int argc, char** argv )
40+
{
41+
cout << "Usage: ./inpaint <image_path>" << endl;
42+
cout << "Keys: " << endl;
43+
cout << "t - inpaint using FMM" << endl;
44+
cout << "n - inpaint using NS technique" << endl;
45+
cout << "r - reset the inpainting mask" << endl;
46+
cout << "ESC - exit" << endl;
47+
48+
string filename;
49+
if(argc > 1)
50+
filename = argv[1];
51+
else
52+
filename = "sample.jpeg";
53+
54+
// Read image in color mode
55+
img = imread(filename, IMREAD_COLOR);
56+
Mat img_mask;
57+
// Return error if image not read properly
58+
if(img.empty())
59+
{
60+
cout << "Failed to load image: " << filename << endl;
61+
return 0;
62+
}
63+
64+
namedWindow("image", WINDOW_AUTOSIZE);
65+
66+
// Create a copy for the original image
67+
img_mask = img.clone();
68+
// Initialize mask (black image)
69+
inpaintMask = Mat::zeros(img_mask.size(), CV_8U);
70+
71+
// Show the original image
72+
imshow("image", img);
73+
setMouseCallback( "image", onMouse, NULL);
74+
75+
for(;;)
76+
{
77+
char c = (char)waitKey();
78+
if (c == 't') {
79+
// Use Algorithm proposed by Alexendra Telea
80+
inpaint(img, inpaintMask, res, 3, INPAINT_TELEA);
81+
imshow("Inpaint Output using FMM", res);
82+
}
83+
if (c == 'n') {
84+
// Use Algorithm proposed by Bertalmio et. al.
85+
inpaint(img, inpaintMask, res, 3, INPAINT_NS);
86+
imshow("Inpaint Output using NS Technique", res);
87+
}
88+
if (c == 'r') {
89+
inpaintMask = Scalar::all(0);
90+
img_mask.copyTo(img);
91+
imshow("image", inpaintMask);
92+
}
93+
if ( c == 27 )
94+
break;
95+
}
96+
return 0;
97+
}

Image-Inpainting/inpaint.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import numpy as np
2+
import cv2 as cv
3+
import sys
4+
5+
# OpenCV Utility Class for Mouse Handling
6+
class Sketcher:
7+
def __init__(self, windowname, dests, colors_func):
8+
self.prev_pt = None
9+
self.windowname = windowname
10+
self.dests = dests
11+
self.colors_func = colors_func
12+
self.dirty = False
13+
self.show()
14+
cv.setMouseCallback(self.windowname, self.on_mouse)
15+
16+
def show(self):
17+
cv.imshow(self.windowname, self.dests[0])
18+
cv.imshow(self.windowname + ": mask", self.dests[1])
19+
20+
# onMouse function for Mouse Handling
21+
def on_mouse(self, event, x, y, flags, param):
22+
pt = (x, y)
23+
if event == cv.EVENT_LBUTTONDOWN:
24+
self.prev_pt = pt
25+
elif event == cv.EVENT_LBUTTONUP:
26+
self.prev_pt = None
27+
28+
if self.prev_pt and flags & cv.EVENT_FLAG_LBUTTON:
29+
for dst, color in zip(self.dests, self.colors_func()):
30+
cv.line(dst, self.prev_pt, pt, color, 5)
31+
self.dirty = True
32+
self.prev_pt = pt
33+
self.show()
34+
35+
36+
def main():
37+
38+
print("Usage: python inpaint <image_path>")
39+
print("Keys: ")
40+
print("t - inpaint using FMM")
41+
print("n - inpaint using NS technique")
42+
print("r - reset the inpainting mask")
43+
print("ESC - exit")
44+
45+
# Read image in color mode
46+
img = cv.imread(sys.argv[1], cv.IMREAD_COLOR)
47+
48+
# If image is not read properly, return error
49+
if img is None:
50+
print('Failed to load image file: {}'.format(args["image"]))
51+
return
52+
53+
# Create a copy of original image
54+
img_mask = img.copy()
55+
# Create a black copy of original image
56+
# Acts as a mask
57+
inpaintMask = np.zeros(img.shape[:2], np.uint8)
58+
# Create sketch using OpenCV Utility Class: Sketcher
59+
sketch = Sketcher('image', [img_mask, inpaintMask], lambda : ((255, 255, 255), 255))
60+
61+
while True:
62+
ch = cv.waitKey()
63+
if ch == 27:
64+
break
65+
if ch == ord('t'):
66+
# Use Algorithm proposed by Alexendra Telea: Fast Marching Method (2004)
67+
# Reference: https://pdfs.semanticscholar.org/622d/5f432e515da69f8f220fb92b17c8426d0427.pdf
68+
res = cv.inpaint(src=img_mask, inpaintMask=inpaintMask, inpaintRadius=3, flags=cv.INPAINT_TELEA)
69+
cv.imshow('Inpaint Output using FMM', res)
70+
if ch == ord('n'):
71+
# Use Algorithm proposed by Bertalmio, Marcelo, Andrea L. Bertozzi, and Guillermo Sapiro: Navier-Stokes, Fluid Dynamics, and Image and Video Inpainting (2001)
72+
res = cv.inpaint(src=img_mask, inpaintMask=inpaintMask, inpaintRadius=3, flags=cv.INPAINT_NS)
73+
cv.imshow('Inpaint Output using NS Technique', res)
74+
if ch == ord('r'):
75+
img_mask[:] = img
76+
inpaintMask[:] = 0
77+
sketch.show()
78+
79+
print('Completed')
80+
81+
82+
if __name__ == '__main__':
83+
main()
84+
cv.destroyAllWindows()

Image-Inpainting/sample.jpeg

10.7 KB
Loading

Image-Inpainting/thresholdimage.png

9.87 KB
Loading

0 commit comments

Comments
 (0)