簡體   English   中英

使用 opencv 獲取蒙版后如何模糊圖像?

[英]How to blur an image after obtaining its mask using opencv?

我遵循了基於顏色分割的模糊圖像指南: https://realpython.com/python-opencv-color-spaces/

但是我很難讓它只模糊原始圖像中的尼莫。

到目前為止,我沒有遵循指南:

import matplotlib.pyplot as plt
import cv2

nemo = cv2.imread('nemo.png')
nemo = cv2.cvtColor(nemo, cv2.COLOR_BGR2RGB)
hsv_nemo = cv2.cvtColor(nemo, cv2.COLOR_RGB2HSV)

light_orange = (1, 190, 200)
dark_orange = (18, 255, 255)
light_white = (0, 0, 200)
dark_white = (145, 60, 255)

mask = cv2.inRange(hsv_nemo, light_orange, dark_orange)
mask_white = cv2.inRange(hsv_nemo, light_white, dark_white)
final_mask = mask + mask_white

final_result = cv2.bitwise_and(nemo, nemo, mask=final_mask)
blur = cv2.blur(final_result, (15, 15), 0)

我在此處繪制了 1) nemo 、2) final_mask和 3) blur以進行比較:圖像結果

有沒有辦法讓我模糊原始照片中的尼莫,使其看起來像這樣:模糊原始照片

目前它只會模糊蒙版圖像中的 nemo。

我想我需要獲得一個 ROI 才能這樣做,但是如何形成蒙版與從原始照片中獲取 nemo 的坐標/ ROI 之間的關系? 謝謝!

如果您只想在蒙版為真的情況下模糊圖像,則應使用類似的方法

blur = cv2.blur(nemo,(15,15),0)
out = nemo.copy()
out[mask>0] = blur[mask>0]

但是,您可能要更改蒙版的生成方式,因為當前它只會使魚的橙色和白色部分模糊。

這是一個適用於 Vec3b 但僅查看通道 0 的答案。它尊重蒙版,僅在沒有蒙版的地方模糊。 這可以防止內部遮罩區域邊緣出現“光暈”效應。 在我的情況下,它是一個球,圓的外部被遮住了,而且眩光點也從球上反射出來。

    void MyPipelineCPU::MyBlur(Mat& src, Mat& mask, Mat& dst, const int diameter) {
    if (dst.empty() || dst.rows != src.rows || dst.cols != src.cols || dst.type() != src.type())
        dst = Mat::zeros(src.rows, src.cols, src.type());

    const int diamter2 = diameter * diameter;
    const int radius = diameter / 2;
    const int radius2 = radius * radius;
    const int rowmax = src.rows - radius;
    const int colmax = src.cols - radius;
    for (int r = radius; r < rowmax; r++) {
        for (int c = radius; c < colmax; c++) {
            uchar msk = mask.at<uchar>(r, c);
            if (msk) {
                Vec3b& srcP = src.at<Vec3b>(r, c);
                Vec3b& dstP = dst.at<Vec3b>(r, c);

                // It is treated as a grey image even though three channels
                int sum0 = 0;
                int count0 = 0;
                for (int dy = -radius; dy <= radius; dy++) {
                    for (int dx = -radius; dx <= radius; dx++) {
                        if (mask.at<uchar>(r + dy, c + dx)) {
                            const Vec3b& pp = src.at<Vec3b>(r + dy, c + dx);
                            sum0 += pp[0];
                            count0++;
                        }
                    }
                }

                if (count0 > 4) {
                    const int avg0 = sum0 / count0;
                    // Blur
                    dstP[0] = avg0;
                    dstP[1] = avg0;
                    dstP[2] = avg0;
                }
                else {
                    dstP[0] = 0;
                    dstP[1] = 0;
                    dstP[2] = 0;
                }
            }
            else {
                Vec3b& dstP = dst.at<Vec3b>(r, c);
                dstP[0] = 0;
                dstP[1] = 0;
                dstP[2] = 0;
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM