2016-04-25 11 views
4

Ich habe eine ROI und ein Bild. Ich muss den ROI mit dem Bild füllen, das ich habe. Das Bild sollte entsprechend der ROI-Form und -Größe skaliert werden und die gesamte ROI ausfüllen, ohne das Bild zu wiederholen. Wie kann ich dies mit opencv erreichen? Gibt es eine Methode in opencv, um dies zu erreichen?Ein Bild an eine ROI anpassen

Angenommen, dieser weiße Abschnitt mein ROI und

suppose this is the ROI

dies mein Eingangsbild enter image description here

Gibt es eine Lösung mit ImageMagick ist ???

+0

ROI bedeutet Rect Of Interest. Sie sollten Ihre Frage bearbeiten, um verstanden zu werden. – sturkmen

+0

@sturkmen Ja .. Ich habe 2 Bilder .. Und ein Bild sollte zum ROI eines anderen Bildes passen – Neeraj

+3

@sturkmen Roi bedeutet Region of interest ... – Neeraj

Antwort

2

optimale Passform von einer Form in einer anderen zu finden, ist nicht trivial, aber wenn Sie für suboptimale Ergebnis abrechnen können Sie folgendes tun:

import cv2 
import numpy as np 
from matplotlib import pyplot as plt 

bg_contours, bg_hierarchy = cv2.findContours(bg_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
bg_contour = bg_contours[0] 
bg_ellipse = cv2.fitEllipse(bg_contour) 

p_contours, p_hierarchy = cv2.findContours(fruit_alpha, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 

pear_hull = cv2.convexHull(p_contours[0]) 
pear_ellipse = cv2.fitEllipse(pear_hull) 

min_ratio = min(bg_ellipse[1][0]/pear_ellipse[1][0], bg_ellipse[1][1]/pear_ellipse[1][1]) 

x_shift = bg_ellipse[0][0] - pear_ellipse[0][0] * min_ratio 
y_shift = bg_ellipse[0][1] - pear_ellipse[0][1] * min_ratio 

(Heuristik) die Frucht Kontur Größe ändern, mit einer anfänglichen Vermutung starten basierend auf den Ellipsen, verfeinert die Kontur (dies muss verbessert werden kann, aber es ist ein nicht triviales Optimierungsproblem, können Sie mehr here aussehen):

r_contour = np.array([[[int(j) for j in i[0]]] for i in min_ratio * p_contours[max_c_ix]]) 

min_dist, bad_pt = GetMinDist(outer_contour=bg_contour, inner_contour=r_contour, offset=(int(x_shift), int(y_shift))) 
mask_size = max(bg_ellipse[1][0], bg_ellipse[1][1]) 
scale = min_ratio * (mask_size + min_dist)/mask_size 

r_contour = np.array([[[int(j) for j in i[0]]] for i in scale * p_contours[max_c_ix]]) 

die Bilder Kombinieren Sie den Alphakanal mit:

combined = CombineImages(bg, fruit_rgb, fruit_alpha, scale, (int(x_shift), int(y_shift))) 

Utility-Funktionen:

def GetMinDist(outer_contour, inner_contour, offset): 
    min_dist = 10000 
    bad_pt = (0,0) 
    for i_pt in inner_contour: 
     #pt = (float(i_pt[0][0]), float(i_pt[0][1])) 
     pt = (i_pt[0][0] + int(offset[0]), i_pt[0][1] + int(offset[1])) 
     dst = cv2.pointPolygonTest(outer_contour, pt, True) 
     if dst < min_dist: 
      min_dist = dst 
      bad_pt = pt 
    return min_dist, bad_pt 

def CombineImages(mask_img, fruit_img, fruit_alpha, scale, offset): 
    mask_height, mask_width, mask_dim = mask_img.shape 
    combined_img = np.copy(mask_img) 
    resized_fruit = np.copy(mask_img) 
    resized_fruit[:] = 0 
    resized_alpha = np.zeros((mask_height, mask_width), fruit_alpha.dtype) 
    f_height, f_width, f_dim = fruit_img.shape 
    r_fruit = cv2.resize(fruit_img, (int(f_width*scale), int(f_height*scale))) 
    r_alpha = cv2.resize(fruit_alpha, (int(f_width*scale), int(f_height*scale))) 
    height, width, channels = r_fruit.shape 
    roi_x_from = offset[0] 
    roi_x_to = offset[0] + width 
    roi_y_from = offset[1] 
    roi_y_to = offset[1] + height 
    resized_fruit[roi_y_from:roi_y_to, roi_x_from:roi_x_to, :] = r_fruit 
    resized_alpha[roi_y_from:roi_y_to, roi_x_from:roi_x_to] = r_alpha 
    for y in range(0,mask_height): 
     for x in range(0, mask_width): 
      if resized_alpha[y,x] > 0: 
       combined_img[y,x,:] = resized_fruit[y,x,:] 

    return combined_img 

enter image description here

Ich hoffe, das hilft.

(Ich habe Teile des Codes weggelassen, die nicht zum Verständnis des Flusses beitragen)

+0

eine Sequenz von Funktionen klar dargestellt. Warum wird diese Antwort nicht verifiziert? –