8
votes

Implémenter le flou radial avec OpenCV

Nous aimerions corriger la courbure de champ introduite par une lentille dans une caméra numérique. Nous prévoyons d'utiliser un Masque Digital Unsharp au lieu d'appliquer un flou gaussien, nous aimerions essayer un flou radial, de sorte que l'aiguection ait plus d'impact sur les bords de l'image.

Quel est le moyen le plus simple de créer un flou radial à l'aide d'OPENCV?


1 commentaires

J'étais sur le point de poster la même question. +1


3 Réponses :


0
votes

Je suis intéressé par quelque chose de similaire au flou Photoshop Radial Motion. Si tel est aussi ce que vous recherchez, je pense que la meilleure solution pourrait être un itératif et mélangement ( addPordad ). Peut également être accompli avec Remap . Pseudocode, plus ou moins: xxx


0 commentaires

6
votes

La réponse ci-dessus est proche mais manque quelques éléments clés qui m'ont pris un peu pour comprendre. J'ai changé les cartes de manière à ce qu'ils calculent correctement le zoom et le rétrécissement et les ajoutent / les soustraits des X et Y à chaque position (sinon, vous allez finir simplement par remonter votre image sur un minuscule carré. J'ai aussi changé le / flou Pour * flou Sinon, vos cartes contiendront de très grands nombres et ne sortent tout simplement pas (multiples extrêmement volumineux de chaque position).

float center_x = width/2; //or whatever
float center_y = height/2;
float blur = 0.002; //blur radius per pixels from center. 2px blur at 1000px from center
int iterations = 5;

Mat growMapx, growMapy;
Mat shrinkMapx, shrinkMapy;
for(int x = 0; x < width; x++) {
  for(int y = 0; y < height; y++) {
    growMapx[x,y] = x+((x - center_x)*blur);
    growMapy[x,y] = y+((y - center_y)*blur);
    shrinkMapx[x,y] = x-((x - center_x)*blur);
    shrinkMapy[x,y] = y-((y - center_y)*blur);
  }
}

Mat tmp1, tmp2;
for(int i = 0; i < iterations; i++)  {
  remap(src, tmp1, growMapx, growMapy, CV_INTER_LINEAR); // enlarge
  remap(src, tmp2, shrinkMapx, shrinkMapy, CV_INTER_LINEAR); // shrink
  addWeighted(tmp1, 0.5, tmp2, 0.5, 0, src); // blend back to src
}


0 commentaires

3
votes

Code Python:

w, h = img.shape[:2]

center_x = w / 2
center_y = h / 2
blur = 0.01
iterations = 5

growMapx = np.tile(np.arange(h) + ((np.arange(h) - center_x)*blur), (w, 1)).astype(np.float32)
shrinkMapx = np.tile(np.arange(h) - ((np.arange(h) - center_x)*blur), (w, 1)).astype(np.float32)
growMapy = np.tile(np.arange(w) + ((np.arange(w) - center_y)*blur), (h, 1)).transpose().astype(np.float32)
shrinkMapy = np.tile(np.arange(w) - ((np.arange(w) - center_y)*blur), (h, 1)).transpose().astype(np.float32)

for i in range(iterations):
    tmp1 = cv2.remap(img, growMapx, growMapy, cv2.INTER_LINEAR)
    tmp2 = cv2.remap(img, shrinkMapx, shrinkMapy, cv2.INTER_LINEAR)
    img = cv2.addWeighted(tmp1, 0.5, tmp2, 0.5, 0)


2 commentaires

Petite amélioration avant la boucle d'ivresse (pour éliminer les effets de bordure noires): GrowMapx, GrowMapy = np.abs (growmapx), np.abs (growmapy) et utilisez bordermode = cv2.border_reflect sur les deux appels CV2.REMAP


Comment puis-je le changer pour que le flou radial ne commence pas à un point mais après une section (zone circulaire aussi)? Je voudrais une partie de celle-ci pas floue.