2017-03-04 78 views
1

私は画像と円のゾーンを持っています。私は円のゾーンを除いて、すべてをぼかす必要があります。また、円の輪郭を滑らかにする必要があります。
入力: Inputopencv pythonのグラデーションマスクブレンド

出力は(マスクで画像のredactorでそれを作ったが、私はOpenCVのが唯一のビットマップ・マスクを使用していると思う):今のところ
Output

を私はにISNのpythonのコードを、持っています円の境界がぼやけていない。

def blur_image(cv_image, radius, center, gaussian_core, sigma_x): 
    blurred = cv.GaussianBlur(cv_image, gaussian_core, sigma_x) 
    h, w, d = cv_image.shape 
# masks 
    circle_mask = np.ones((h, w), cv_image.dtype) 
    cv.circle(circle_mask, center, radius, (0, 0, 0), -1) 
    circle_not_mask = np.zeros((h, w), cv_image.dtype) 
    cv.circle(circle_not_mask, center, radius, (2, 2, 2), -1) 
# Computing 
    blur_around = cv.bitwise_and(blurred, blurred, mask=circle_mask) 
    image_in_circle = cv.bitwise_and(cv_image, cv_image, mask=circle_not_mask) 
    res = cv.bitwise_or(blur_around, image_in_circle) 
    return res 

現在のバージョン:
enter image description here どのように私は、円の境界線をぼかすことができますか?出力の例では、プログラムでグラデーションマスクを使用しました。 opencvに似たものがありますか?だから、
UPDATE 04.03
、私はthis answered topicと私が持っているから式を試してみた:
Another try
コード:

def blend_with_mask_matrix(src1, src2, mask): 
    res = src2 * (1 - cv.divide(mask, 255.0)) + src1 * cv.divide(mask, 255.0) 
return res 

このコードは、最近1と同様に動作するはずですが、それはしていません。円のイメージはわずかに異なります。それは色にいくつかの問題があります。 質問はまだ開いています。

+0

[THIS PAGE](http://stackoverflow.com/questions/30101044/how-to-blur-some-portion-of-image-in-android)をご覧ください –

+0

@Jeru私はすでに適切な数式ですが、Pythonに統合することにはいくつか問題があります。 '(mask/255)* blur +(1-mask/255)*他のimg'。私はループなしで動作しようとしていますが、numpyの行列演算を組み込むだけです – 01ghost13

+0

あなたの数式はうまくいきますか? –

答えて

2

したがって、(mask/255) * blur + (1-mask/255)*another imgの主な問題は演算子でした。彼らは1つのチャンネルだけで働いていました。次の問題は、「スムージング」のための浮動小数点数で働いています。
1)私は、ソースイメージのすべてのチャンネルを取って、実行
2)式
3)マージチャンネル

def blend_with_mask_matrix(src1, src2, mask): 
    res_channels = [] 
    for c in range(0, src1.shape[2]): 
     a = src1[:, :, c] 
     b = src2[:, :, c] 
     m = mask[:, :, c] 
     res = cv.add(
      cv.multiply(b, cv.divide(np.full_like(m, 255) - m, 255.0, dtype=cv.CV_32F), dtype=cv.CV_32F), 
      cv.multiply(a, cv.divide(m, 255.0, dtype=cv.CV_32F), dtype=cv.CV_32F), 
      dtype=cv.CV_8U) 
     res_channels += [res] 
    res = cv.merge(res_channels) 
    return res 

をマスクだと:
私はこれにアルファチャンネルとブレンドのコードを変更しました私はちょうどぼんやりした円を使っています。

def blur_image(cv_image, radius, center, gaussian_core, sigma_x): 
    blurred = cv.GaussianBlur(cv_image, gaussian_core, sigma_x) 

    circle_not_mask = np.zeros_like(cv_image) 
    cv.circle(circle_not_mask, center, radius, (255, 255, 255), -1) 
#Smoothing borders 
    cv.GaussianBlur(circle_not_mask, (101, 101), 111, dst=circle_not_mask) 
# Computing 
    res = blend_with_mask_matrix(cv_image, blurred, circle_not_mask) 
    return res 

結果:

Result それはスムーズに国境なしで非常に最初のバージョンよりも少し遅く働いているが、それは大丈夫です。
締め切りの質問。

+0

ありがとうございました。ソリューションを投稿します。本当に助けます。この回答を確認することもできます –

0

あなたは簡単に以下のfuncitonを使用して画像にマスクすることができます。

def transparentOverlay(src, overlay, pos=(0, 0), scale=1): 
    overlay = cv2.resize(overlay, (0, 0), fx=scale, fy=scale) 
    h, w, _ = overlay.shape # Size of foreground 
    rows, cols, _ = src.shape # Size of background Image 
    y, x = pos[0], pos[1] # Position of foreground/overlay image 

    # loop over all pixels and apply the blending equation 
    for i in range(h): 
     for j in range(w): 
      if x + i >= rows or y + j >= cols: 
       continue 
      alpha = float(overlay[i][j][3]/255.0) # read the alpha channel 
      src[x + i][y + j] = alpha * overlay[i][j][:3] + (1 - alpha) * src[x + i][y + j] 
    return src 

はあなたがマスクを設定したいソース画像は、オーバーレイマスクと位置を渡す必要があります。 マスキングスケールを設定することもできます。このように呼び出すことによって。このリンクで見ることができます詳細について

transparentOverlay(face_cigar_roi_color,cigar,(int(w/2),int(sh_cigar/2))) 

Face masking and Overlay using OpenCV python

出力:

Face Masking Demo

0

私は多分あなたはそのような何かをしたいと思います。

これはソース画像ある:マスクalphablened対 enter image description here

enter image description here

enter image description here

ソースblured対


コードコメントの説明のあるコード。

#!/usr/bin/python3 
# 2018.01.16 13:07:05 CST 
# 2018.01.16 13:54:39 CST 
import cv2 
import numpy as np 

def alphaBlend(img1, img2, mask): 
    """ alphaBlend img1 and img 2 (of CV_8UC3) with mask (CV_8UC1 or CV_8UC3) 
    """ 
    if mask.ndim==3 and mask.shape[-1] == 3: 
     alpha = mask/255.0 
    else: 
     alpha = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)/255.0 
    blended = cv2.convertScaleAbs(img1*(1-alpha) + img2*alpha) 
    return blended 

img = cv2.imread("test.png") 

H,W = img.shape[:2] 
mask = np.zeros((H,W), np.uint8) 
cv2.circle(mask, (325, 350), 40, (255,255,255), -1, cv2.LINE_AA) 
mask = cv2.GaussianBlur(mask, (21,21),11) 

blured = cv2.GaussianBlur(img, (21,21), 11) 

blended1 = alphaBlend(img, blured, mask) 
blended2 = alphaBlend(img, blured, 255- mask) 

cv2.imshow("blened1", blended1); 
cv2.imshow("blened2", blended2); 
cv2.waitKey();cv2.destroyAllWindows() 

いくつかの便利なリンク:OpenCVのC++で

  1. アルファブレンディング:OpenCVのPythonでCombining 2 images with transparent mask in opencv

  2. アルファブレンディング: Gradient mask blending in opencv python