merge comment plus ajout tentative infructueuse

master
Ludovic CASTIGLIA 4 months ago
parent bfe218a9c1
commit 2080bbc784

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

@ -0,0 +1,164 @@
from matplotlib.widgets import RectangleSelector
import matplotlib.pyplot as plt
from random import randint
import numpy as np
def initialPatchMatch(img,x1,y1,x2,y2,patchSize=129):
def getDist(pValue1, pValue2):
return np.sum((pValue1 - pValue2) ** 2)
def initializePermimiter(finish=False):
perimeter = []
for x in range(x1, x2 + 1):
perimeter.append((x, y1))
perimeter.append((x, y2))
if finish:
perimeter.append((x,y1-1))
perimeter.append((x,y2+1))
for y in range(y1 + 1, y2):
perimeter.append((x1, y))
perimeter.append((x2, y))
if finish:
perimeter.append((x1-1,y))
perimeter.append((x2+1,y))
return np.array(perimeter)
def getRandomPatchFromPerimiter(perimiter):
x,y = perimiter[np.random.randint(len(perimiter))]
patch = np.array([[i, j] for i in range(x - semiPatch, x + semiPatch + 1)
for j in range(y - semiPatch, y + semiPatch + 1)])
return patch
def getZoneMask(zoneValue,outside):
mask = []
for value in zoneValue:
mask.append((value.sum() == 0) ^outside)
return np.array(mask)
def applyMask(patch,mask,oposed=False):
return patch[mask^oposed]
def getValueFromPatch(patch):
ret = img[patch[0][1]:patch[0][1]+patchSize,patch[0][0]:patch[0][0]+patchSize]
ret = ret.transpose(1, 0, 2)
return ret.reshape(-1, 3)
def getRandomPatch(patchCoordFound):
if (len(patchCoordFound) == 0):
#TODO peut être trouver un patch autour du trou et verrifier que pas dans le trou
x = randint(semiPatch,width-semiPatch-1)
y = randint(semiPatch,height-semiPatch-1)
patch = np.array([[i, j] for i in range(x - semiPatch, x + semiPatch + 1)
for j in range(y - semiPatch, y + semiPatch + 1)])
else:
patch = patchCoordFound[randint(0,len(patchCoordFound)-1)]
return patch
def getBestNeigbourPatch(zoneMask,filteredZoneValue,dist,patch,offset):
voisin = [[-1,-1],[-1,0],[0,-1],[0,0],[1,-1],[-1,1],[0,1],[1,0],[1,1]]
found = False
bPatch = []
for x,y in voisin:
nPatch = patch.copy()
nPatch[:,0] += x*offset
nPatch[:,1] += y*offset
if np.any(nPatch < 0) or np.any(nPatch[:,0] >= width) or np.any(nPatch[:,1] >= height):
#TODO verrifier que le patch est pas dans le troue si non ff
continue
nPatchValue = getValueFromPatch(nPatch)
filteredPatchValue = applyMask(nPatchValue,zoneMask)
nDist = getDist(filteredZoneValue,filteredPatchValue)
if (nDist < dist):
dist = nDist
bPatch = nPatch
found = True
return found,bPatch,dist
def getBestPatchForZone(zoneValue,zoneMask,patchCoordFound):
filteredZoneValue = applyMask(zoneValue,zoneMask)
patch = getRandomPatch(patchCoordFound)
patchValue = getValueFromPatch(patch)
filteredPatchValue = applyMask(patchValue,zoneMask)
dist = getDist(filteredZoneValue,filteredPatchValue)
offset = 1
while offset < min(width,height):
found, nPatch,nDist = getBestNeigbourPatch(zoneMask,filteredZoneValue,dist,patch,offset)
if (found):
patch = nPatch
dist = nDist
offset = 1
else:
offset*=2
patchCoordFound.append(patch)
return patchValue
def applyPatch(filteredZone,zoneMask, patchValue):
filteredPatchValue = applyMask(patchValue,zoneMask,True)
for i in range(len(filteredZone)) :
img[filteredZone[i][1],filteredZone[i][0]] = filteredPatchValue[i]
def updatePerimiter(filteredZone,perimiter):
for x,y in filteredZone:
if ((x,y) in filteredZone):
perimiter = np.delete(perimiter, np.where((perimiter == [x, y]).all(axis=1))[0], axis=0)
voisin = [[-1,-1],[-1,0],[0,-1],[0,0],[1,-1],[-1,1],[0,1],[1,0],[1,1]]
for x,y in filteredZone:
for offsetx,offsety in voisin:
if img[y+offsety,x+offsetx].sum() == 0:
perimiter = np.vstack((perimiter, [x+offsetx, y+offsety]))
return perimiter
def addEdge(edges,zone):
# pas des deux coté car zone pas filteredZone pour endroit biscornue
x,y = zone[0]
for xx in range(x,x+patchSize):
if x1<=xx<=x2:
if y1<=y<=y2:
edges.append([xx,y])
if y1<=y+patchSize<=y2:
edges.append([xx,y+patchSize])
for yy in range(y,y+patchSize):
if y1<=yy<=y2:
if x1<=x<=x2:
edges.append([x,yy])
if x1<=x+patchSize<=x2:
edges.append([x+patchSize,yy])
return edges
def smoothEdges(edges):
perimiter = initializePermimiter(True)
edges.extend(perimiter.tolist())
edges = np.array(edges)
offsets = np.array([[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]])
for edge in edges:
neighbors = edge + offsets[:,None]
neighbors = neighbors.reshape(-1,2)
valid_neighbors = neighbors[
(neighbors[:,0] >= 0) & (neighbors[:,0] < width) &
(neighbors[:,1] >= 0) & (neighbors[:,1] < height)
]
if len(valid_neighbors) > 0:
neighbor_values = img[valid_neighbors[:,1], valid_neighbors[:,0]]
avg_value = np.mean(neighbor_values, axis=0)
img[edge[1], edge[0]] = avg_value
semiPatch = int(patchSize/2)
height, width, _ = img.shape
patchCoordFound = []
edges = []
perimiter = initializePermimiter()
while len(perimiter)> 0:
zone = getRandomPatchFromPerimiter(perimiter)
edges = addEdge(edges,zone)
zoneValue = getValueFromPatch(zone)
zoneMask = getZoneMask(zoneValue,True)
filteredZoneInside = applyMask(zone,zoneMask,True)
patchValue = getBestPatchForZone(zoneValue,zoneMask,patchCoordFound)
applyPatch(filteredZoneInside,zoneMask,patchValue)
perimiter = updatePerimiter(filteredZoneInside,perimiter)
smoothEdges(edges)
return img

@ -0,0 +1,83 @@
from matplotlib.widgets import RectangleSelector
import matplotlib.pyplot as plt
import numpy as np
def doKnn(img,x1,y1,x2,y2):
def getNotInBoundNeighbour(neighbour, x1,y1,x2,y2):
mask = np.logical_or(
np.logical_or(neighbour[:, 0] < y1, neighbour[:, 0] > y2),
np.logical_or(neighbour[:, 1] < x1, neighbour[:, 1] > x2)
)
return neighbour[mask]
def neighbourReelPixel(x,y):
tNeighbour = np.copy(neighbour)
tNeighbour = tNeighbour + np.array([y,x])
return tNeighbour
def getAvgPixelFromNeighbour(neighbour):
return np.mean(img[neighbour[:,0],neighbour[:,1]], axis=0)
neighbour = np.array([[-1,-1],[-1,0],[0,-1],[-1,1],[1,-1],[0,1],[1,0],[1,1]])
x1c = x1
y1c = y1
x2c = x2
y2c = y2
# tant que les pixels en périphérie du trou ne se rejoignent pas alors le trou n'est pas comblé
while x1 != x2 and y1 != y2:
# on comble les pixels à gauche et à droite
for x in range(x1,x2):
currentNeighbour1 = neighbourReelPixel(x,y1)
currentNeighbour2 = neighbourReelPixel(x,y2)
currentNeighbour1 = getNotInBoundNeighbour(currentNeighbour1,x1,y1,x2,y2)
currentNeighbour2 = getNotInBoundNeighbour(currentNeighbour2,x1,y1,x2,y2)
currentColor1 = getAvgPixelFromNeighbour(currentNeighbour1)
currentColor2 = getAvgPixelFromNeighbour(currentNeighbour2)
img[y1,x] = currentColor1
img[y2,x] = currentColor2
# puis en haut et en bas
for y in range(y1,y2):
currentNeighbour1 = neighbourReelPixel(x1,y)
currentNeighbour2 = neighbourReelPixel(x2,y)
currentNeighbour1 = getNotInBoundNeighbour(currentNeighbour1,x1,y1,x2,y2)
currentNeighbour2 = getNotInBoundNeighbour(currentNeighbour2,x1,y1,x2,y2)
currentColor1 = getAvgPixelFromNeighbour(currentNeighbour1)
currentColor2 = getAvgPixelFromNeighbour(currentNeighbour2)
img[y,x1] = currentColor1
img[y,x2] = currentColor2
x1 += 1
x2 -= 1
y1 += 1
y2 -= 1
for x in range(x1c, x2c):
for y in range(y1c, y2c):
currentNeighbour = neighbourReelPixel(x, y)
currentNeighbour = getNotInBoundNeighbour(currentNeighbour,0,0,0,0)
currentColor = getAvgPixelFromNeighbour(currentNeighbour)
img[y, x] = currentColor
img[y1:y2,x1:x2]
return img
img = plt.imread('asset/boat.png')
if len(img.shape) == 2:
img = np.stack((img,)*3, axis=-1)
def onselect(eclick, erelease):
x1, y1 = eclick.xdata, eclick.ydata
x2, y2 = erelease.xdata, erelease.ydata
img_copy = np.copy(img)
res = doKnn(img_copy,int(x1),int(y1),int(x2),int(y2))
ax.imshow(res)
plt.draw()
fig, ax = plt.subplots()
ax.imshow(img)
toggle_selector = RectangleSelector(ax, onselect, useblit=True,
button=[1], minspanx=5, minspany=5, spancoords='pixels',
interactive=True)
plt.axis('off')
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

@ -0,0 +1,156 @@
from matplotlib.widgets import RectangleSelector
import matplotlib.pyplot as plt
from random import randint
import numpy as np
import cv2
import time
from function import *
def reScale(img,scale):
height, width = img.shape[:2]
new_height = int(height / scale)
new_width = int(width / scale)
scaled_img = cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_AREA)
return scaled_img, new_height,new_width
def reScaleCoord(oWidth,oHeight,nWidth,nHeight,x1,y1,x2,y2):
x1, x2 = int(x1*nWidth/oWidth),int(x2*nWidth/oWidth)
y1, y2 = int(y1*nHeight/oHeight),int(y2*nHeight/oHeight)
return x1,y1,x2,y2
def getDist(pValue1, pValue2):
return np.sum((pValue1 - pValue2) ** 2)
def getRandomPatch(img2,pSize,x1,y1,x2,y2):
height, width = img2.shape[:2]
x = [randint(0,x1),randint(x2,width-pSize)][randint(0,1)]
y = [randint(0,y1),randint(y2,height-pSize)][randint(0,1)]
patch = getZoneFromCoord(x,y,pSize)
return patch
def getValueFromPatch(img,patch,pSize):
ret = img[patch[0][1]:patch[0][1]+pSize,patch[0][0]:patch[0][0]+pSize]
ret = ret.transpose(1, 0, 2)
return ret.reshape(-1, 3)
def applyPatch(img,zone,patchValue):
for i in range(len(zone)) :
img[zone[i][1],zone[i][0]] = patchValue[i]
return img
def findBestPatchFromNeigbour(zoneValue,oDist,patch,offset,height,width,img,pSize):
neigbour = [[-1,-1],[-1,0],[0,-1],[-1,1],[1,-1],[0,1],[1,0],[1,1]]
trouve = False
rP = patch
for x,y in neigbour:
p = patch.copy()
p[:,0] += x*offset
p[:,1] += y*offset
if np.any(p < 0) or np.any(p[:,0] >= width) or np.any(p[:,1] >= height):
continue
value = getValueFromPatch(img,p,pSize)
dist = getDist(zoneValue,value)
if (dist < oDist):
trouve = True
oDist = dist
rP = p
return trouve, rP, oDist
def findBestPatch(img2,zone,zoneValue,pSize,pixSize,height,width,x1,y1,x2,y2):
if not (x1<=zone[0][0]<=x2 and y1<=zone[0][1]):
patch = zone.copy()
return patch
patch = getRandomPatch(img2,int(pSize/pixSize)*2,x1,y1,x2,y2)
pValue = getValueFromPatch(img2,patch,pSize)
pdist = getDist(zoneValue,pValue)
for i in range(500):
tpatch = getRandomPatch(img2,int(pSize/pixSize)*2,x1,y1,x2,y2)
tpValue = getValueFromPatch(img2,tpatch,pSize)
tpdist = getDist(zoneValue,tpValue)
if tpdist<pdist:
pdist = tpdist
patch = tpatch
offset = 1
while offset < min(height,width)/3:
found, nPatch,nDist = findBestPatchFromNeigbour(zoneValue,pdist,patch,int(offset),height,width,img2,pSize)
if found:
patch = nPatch
pdist = nDist
offset = 1
else:
offset*=2
return patch
def getZoneFromCoord(x,y,patchSize):
zone = np.array([[i, j] for i in range(x, x + patchSize)
for j in range(y, y + patchSize)])
return zone
def rebuildImg(img1,img2,pixSize,x1,y1,x2,y2):
height,width = img1.shape[:2]
pSize = pixSize * 2
for x in range(int(width/pSize)):
for y in range(int(height/pSize)):
zone = getZoneFromCoord(x*pSize,y*pSize,pSize)
if not (x1<=x*pSize<=x2 and y1<=y*pSize<=y2):
zoneValue = getValueFromPatch(img2,zone,pSize)
applyPatch(img1,zone,zoneValue)
continue
zoneValue = getValueFromPatch(img1,zone,pSize)
patch = findBestPatch(img2,zone,zoneValue,pSize,pixSize,height,width,x1,y1,x2,y2)
patchValue = getValueFromPatch(img2,patch,pSize)
img1 = applyPatch(img1,zone,patchValue)
return img1
def doPatchMatch(image,x1,y1,x2,y2,scaleFactor=20,patchSize=129):
oHeight, oWidth = image.shape[:2]
rImage, nHeight, nWidth = reScale(image,scaleFactor)
nx1, ny1, nx2, ny2 = reScaleCoord(oWidth,oHeight,nWidth,nHeight,x1,y1,x2,y2)
rImage[ny1:ny2+1, nx1:nx2+1] = 0
rImage = initialPatchMatch(rImage,nx1,ny1,nx2,ny2,5)
while scaleFactor != 2:
scaleFactor -= 1
rImage, nHeight, nWidth = reScale(rImage,scaleFactor/(scaleFactor+1))
timg, h,w = reScale(image,scaleFactor)
nx1, ny1, nx2, ny2 = reScaleCoord(oWidth,oHeight,w,h,x1,y1,x2,y2)
rImage = rebuildImg(rImage,timg,int(h/nHeight),nx1,ny1,nx2,ny2)
tempRes, _, _= reScale(rImage,1/scaleFactor)
ax.imshow(tempRes)
plt.draw()
plt.pause(0.1)
nHeight = h
print(scaleFactor)
return tempRes
img = plt.imread('asset/vache.png')
if img.dtype == np.float32:
img = (img * 255).astype(np.uint8)
img = img[:,:,0:3]
def onselect(eclick, erelease):
x1, y1 = eclick.xdata, eclick.ydata
x2, y2 = erelease.xdata, erelease.ydata
print("drawing")
img_copy = np.copy(img)
res = doPatchMatch(img_copy,int(x1),int(y1),int(x2),int(y2))
ax.imshow(res)
plt.draw()
print("drawed")
fig, ax = plt.subplots()
ax.imshow(img)
toggle_selector = RectangleSelector(ax, onselect, useblit=True,
button=[1], minspanx=5, minspany=5, spancoords='pixels',
interactive=True)
plt.axis('off')
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

@ -0,0 +1,166 @@
from matplotlib.widgets import RectangleSelector
import matplotlib.pyplot as plt
from random import randint
import numpy as np
def doPatchMatch(img,x1,y1,x2,y2,patchSize=65):
def getDist(pValue1, pValue2):
return np.sum((pValue1 - pValue2) ** 2)
def initializePermimiter():
perimeter = []
for x in range(x1, x2 + 1):
perimeter.append((x, y1))
perimeter.append((x, y2))
for y in range(y1 + 1, y2):
perimeter.append((x1, y))
perimeter.append((x2, y))
img[y1:y2+1, x1:x2+1] = 0
return np.array(perimeter)
def getRandomPatchFromPerimiter(perimiter):
x,y = perimiter[np.random.randint(len(perimiter))]
patch = np.array([[i, j] for i in range(x - semiPatch, x + semiPatch + 1)
for j in range(y - semiPatch, y + semiPatch + 1)])
return patch
def getZoneMask(zoneValue,outside):
mask = []
for value in zoneValue:
mask.append((value.sum() == 0) ^outside)
return np.array(mask)
def applyMask(patch,mask,oposed=False):
patchf = []
for i in range(len(mask)):
if(mask[i]^oposed):
patchf.append(patch[i])
return np.array(patchf)
def getValueFromPatch(patch):
value = []
for x,y in patch:
value.append(img[y,x])
return np.array(value)
def getRandomPatch(patchCoordFound):
if (len(patchCoordFound) ==0):
#TODO peut être trouver un patch autour du trou et verrifier que pas dans le trou
x = randint(semiPatch,width-semiPatch-1)
y = randint(semiPatch,height-semiPatch-1)
patch = np.array([[i, j] for i in range(x - semiPatch, x + semiPatch + 1)
for j in range(y - semiPatch, y + semiPatch + 1)])
else:
patch = patchCoordFound[randint(0,len(patchCoordFound)-1)]
return patch
def getBestNeigbourPatch(zoneMask,filteredZoneValue,dist,patch,offset):
voisin = [[-1,-1],[-1,0],[0,-1],[0,0],[1,-1],[-1,1],[0,1],[1,0],[1,1]]
found = False
bPatch = []
for x,y in voisin:
nPatch = patch.copy()
nPatch[:,0] += x*offset
nPatch[:,1] += y*offset
if np.any(nPatch < 0) or np.any(nPatch[:,0] >= width) or np.any(nPatch[:,1] >= height):
#TODO verrifier que le patch est pas dans le troue si non ff
continue
nPatchValue = getValueFromPatch(nPatch)
filteredPatchValue = applyMask(nPatchValue,zoneMask)
nDist = getDist(filteredZoneValue,filteredPatchValue)
if (nDist < dist):
dist = nDist
bPatch = nPatch
found = True
return found,bPatch,dist
def getBestPatchForZone(zoneValue,zoneMask,patchCoordFound):
filteredZoneValue = applyMask(zoneValue,zoneMask)
patch = getRandomPatch(patchCoordFound)
patchValue = getValueFromPatch(patch)
filteredPatchValue = applyMask(patchValue,zoneMask)
dist = getDist(filteredZoneValue,filteredPatchValue)
offset = 1
while offset < min(width,height)/3:
found, nPatch,nDist = getBestNeigbourPatch(zoneMask,filteredZoneValue,dist,patch,offset)
if (found):
patch = nPatch
dist = nDist
offset = 1
else:
offset*=2
patchCoordFound.append(patch)
return patchValue
def applyPatch(zoneCoord,zoneMask, patchValue):
filteredPatchValue = applyMask(patchValue,zoneMask,True)
filteredZone = applyMask(zoneCoord,zoneMask,True)
for i in range(len(filteredZone)) :
img[filteredZone[i][1],filteredZone[i][0]] = filteredPatchValue[i]
def updatePerimiter(zone,zoneMask,perimiter):
filteredZone = applyMask(zone,zoneMask,True)
for x,y in filteredZone:
if ((x,y) in filteredZone):
perimiter = np.delete(perimiter, np.where((perimiter == [x, y]).all(axis=1))[0], axis=0)
voisin = [[-1,-1],[-1,0],[0,-1],[0,0],[1,-1],[-1,1],[0,1],[1,0],[1,1]]
for x,y in filteredZone:
for offsetx,offsety in voisin:
if img[y+offsety,x+offsetx].sum() == 0:
perimiter = np.vstack((perimiter, [x+offsetx, y+offsety]))
return perimiter
semiPatch = int(patchSize/2)
height, width, _ = img.shape
patchCoordFound = []
eadges = []
perimiter = initializePermimiter()
it = 0
while len(perimiter)> 0:
zone = getRandomPatchFromPerimiter(perimiter)
zoneValue = getValueFromPatch(zone)
zoneMask = getZoneMask(zoneValue,True)
patchValue = getBestPatchForZone(zoneValue,zoneMask,patchCoordFound)
applyPatch(zone,zoneMask,patchValue)
perimiter = updatePerimiter(zone,zoneMask,perimiter)
it +=1
print(it)
return img
# for x, y in zone:
# if 0 <= x < width and 0 <= y < height:
# img[y, x] = [255, 255, 255]
# return img
img = plt.imread('asset/mur.jpg')
if img.dtype == np.float32:
img = (img * 255).astype(np.uint8)
img = img[:,:,0:3]
def onselect(eclick, erelease):
x1, y1 = eclick.xdata, eclick.ydata
x2, y2 = erelease.xdata, erelease.ydata
print("drawing")
img_copy = np.copy(img)
res = doPatchMatch(img_copy,int(x1),int(y1),int(x2),int(y2))
ax.imshow(res)
plt.draw()
print("drawed")
fig, ax = plt.subplots()
ax.imshow(img)
toggle_selector = RectangleSelector(ax, onselect, useblit=True,
button=[1], minspanx=5, minspany=5, spancoords='pixels',
interactive=True)
plt.axis('off')
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

@ -0,0 +1,196 @@
from matplotlib.widgets import RectangleSelector
import matplotlib.pyplot as plt
from random import randint
import numpy as np
def doPatchMatch(img,x1,y1,x2,y2,patchSize=129):
def getDist(pValue1, pValue2):
return np.sum((pValue1 - pValue2) ** 2)
def initializePermimiter(finish=False):
perimeter = []
for x in range(x1, x2 + 1):
perimeter.append((x, y1))
perimeter.append((x, y2))
if finish:
perimeter.append((x,y1-1))
perimeter.append((x,y2+1))
for y in range(y1 + 1, y2):
perimeter.append((x1, y))
perimeter.append((x2, y))
if finish:
perimeter.append((x1-1,y))
perimeter.append((x2+1,y))
return np.array(perimeter)
def getRandomPatchFromPerimiter(perimiter):
x,y = perimiter[np.random.randint(len(perimiter))]
patch = np.array([[i, j] for i in range(x - semiPatch, x + semiPatch + 1)
for j in range(y - semiPatch, y + semiPatch + 1)])
return patch
def getZoneMask(zoneValue,outside):
mask = []
for value in zoneValue:
mask.append((value.sum() == 0) ^outside)
return np.array(mask)
def applyMask(patch,mask,oposed=False):
return patch[mask^oposed]
def getValueFromPatch(patch):
ret = img[patch[0][1]:patch[0][1]+patchSize,patch[0][0]:patch[0][0]+patchSize]
ret = ret.transpose(1, 0, 2)
return ret.reshape(-1, 3)
def getRandomPatch(patchCoordFound):
if (len(patchCoordFound) == 0):
#TODO peut être trouver un patch autour du trou et verrifier que pas dans le trou
x = randint(semiPatch,width-semiPatch-1)
y = randint(semiPatch,height-semiPatch-1)
patch = np.array([[i, j] for i in range(x - semiPatch, x + semiPatch + 1)
for j in range(y - semiPatch, y + semiPatch + 1)])
else:
patch = patchCoordFound[randint(0,len(patchCoordFound)-1)]
return patch
def getBestNeigbourPatch(zoneMask,filteredZoneValue,dist,patch,offset):
voisin = [[-1,-1],[-1,0],[0,-1],[0,0],[1,-1],[-1,1],[0,1],[1,0],[1,1]]
found = False
bPatch = []
for x,y in voisin:
nPatch = patch.copy()
nPatch[:,0] += x*offset
nPatch[:,1] += y*offset
if np.any(nPatch < 0) or np.any(nPatch[:,0] >= width) or np.any(nPatch[:,1] >= height):
#TODO verrifier que le patch est pas dans le troue si non ff
continue
nPatchValue = getValueFromPatch(nPatch)
filteredPatchValue = applyMask(nPatchValue,zoneMask)
nDist = getDist(filteredZoneValue,filteredPatchValue)
if (nDist < dist):
dist = nDist
bPatch = nPatch
found = True
return found,bPatch,dist
def getBestPatchForZone(zoneValue,zoneMask,patchCoordFound):
filteredZoneValue = applyMask(zoneValue,zoneMask)
patch = getRandomPatch(patchCoordFound)
patchValue = getValueFromPatch(patch)
filteredPatchValue = applyMask(patchValue,zoneMask)
dist = getDist(filteredZoneValue,filteredPatchValue)
offset = 1
while offset < min(width,height)/2:
found, nPatch,nDist = getBestNeigbourPatch(zoneMask,filteredZoneValue,dist,patch,offset)
if (found):
patch = nPatch
dist = nDist
offset = 1
else:
offset*=2
patchCoordFound.append(patch)
return patchValue
def applyPatch(filteredZone,zoneMask, patchValue):
filteredPatchValue = applyMask(patchValue,zoneMask,True)
for i in range(len(filteredZone)) :
img[filteredZone[i][1],filteredZone[i][0]] = filteredPatchValue[i]
def updatePerimiter(filteredZone,perimiter):
for x,y in filteredZone:
if ((x,y) in filteredZone):
perimiter = np.delete(perimiter, np.where((perimiter == [x, y]).all(axis=1))[0], axis=0)
voisin = [[-1,-1],[-1,0],[0,-1],[0,0],[1,-1],[-1,1],[0,1],[1,0],[1,1]]
for x,y in filteredZone:
for offsetx,offsety in voisin:
if img[y+offsety,x+offsetx].sum() == 0:
perimiter = np.vstack((perimiter, [x+offsetx, y+offsety]))
return perimiter
def addEdge(edges,zone):
# pas des deux coté car zone pas filteredZone pour endroit biscornue
x,y = zone[0]
for xx in range(x,x+patchSize):
if x1<=xx<=x2:
if y1<=y<=y2:
edges.append([xx,y])
if y1<=y+patchSize<=y2:
edges.append([xx,y+patchSize])
for yy in range(y,y+patchSize):
if y1<=yy<=y2:
if x1<=x<=x2:
edges.append([x,yy])
if x1<=x+patchSize<=x2:
edges.append([x+patchSize,yy])
return edges
def smoothEdges(edges):
perimiter = initializePermimiter(True)
edges.extend(perimiter.tolist())
edges = np.array(edges)
offsets = np.array([[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]])
for edge in edges:
neighbors = edge + offsets[:,None]
neighbors = neighbors.reshape(-1,2)
valid_neighbors = neighbors[
(neighbors[:,0] >= 0) & (neighbors[:,0] < width) &
(neighbors[:,1] >= 0) & (neighbors[:,1] < height)
]
if len(valid_neighbors) > 0:
neighbor_values = img[valid_neighbors[:,1], valid_neighbors[:,0]]
avg_value = np.mean(neighbor_values, axis=0)
img[edge[1], edge[0]] = avg_value
# for x,y in edges:
# img[y,x] = [255,0,0]
semiPatch = int(patchSize/2)
height, width, _ = img.shape
patchCoordFound = []
edges = []
perimiter = initializePermimiter()
img[y1:y2+1, x1:x2+1] = 0
it = 0
while len(perimiter)> 0:
zone = getRandomPatchFromPerimiter(perimiter)
edges = addEdge(edges,zone)
zoneValue = getValueFromPatch(zone)
zoneMask = getZoneMask(zoneValue,True)
filteredZoneInside = applyMask(zone,zoneMask,True)
patchValue = getBestPatchForZone(zoneValue,zoneMask,patchCoordFound)
applyPatch(filteredZoneInside,zoneMask,patchValue)
perimiter = updatePerimiter(filteredZoneInside,perimiter)
it +=1
print(it)
print("smoothing edges")
smoothEdges(edges)
return img
img = plt.imread('asset/vache.png')
if img.dtype == np.float32:
img = (img * 255).astype(np.uint8)
img = img[:,:,0:3]
def onselect(eclick, erelease):
x1, y1 = eclick.xdata, eclick.ydata
x2, y2 = erelease.xdata, erelease.ydata
print("drawing")
img_copy = np.copy(img)
res = doPatchMatch(img_copy,int(x1),int(y1),int(x2),int(y2))
ax.imshow(res)
plt.draw()
print("drawed")
fig, ax = plt.subplots()
ax.imshow(img)
toggle_selector = RectangleSelector(ax, onselect, useblit=True,
button=[1], minspanx=5, minspany=5, spancoords='pixels',
interactive=True)
plt.axis('off')
plt.show()

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Loading…
Cancel
Save