简体   繁体   English

使用 opencv 获取蒙版后如何模糊图像?

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

I've followed a guide on blurring image based on colour segmentation: https://realpython.com/python-opencv-color-spaces/我遵循了基于颜色分割的模糊图像指南: https://realpython.com/python-opencv-color-spaces/

But I have trouble in getting it to blur only the nemo in the original image.但是我很难让它只模糊原始图像中的尼莫。

What I have so far from following the guide:到目前为止,我没有遵循指南:

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)

I've plotted out 1) nemo , 2) final_mask , and 3) blur for comparison here: Image Result我在此处绘制了 1) nemo 、2) final_mask和 3) blur以进行比较:图像结果

Is there a way for me to blur the nemo in the original photo such that it looks something like this: Blurred Original Photo有没有办法让我模糊原始照片中的尼莫,使其看起来像这样:模糊原始照片

At the moment it only blurs nemo in the mask image.目前它只会模糊蒙版图像中的 nemo。

I think I need to obtain a ROI for me to do so, but how do I form the relationship between a mask and getting the coordinates/ ROI of the nemo from the original photo?我想我需要获得一个 ROI 才能这样做,但是如何形成蒙版与从原始照片中获取 nemo 的坐标/ ROI 之间的关系? Thanks!谢谢!

If you wanted to blur the image only where the mask is true, something like this should work 如果您只想在蒙版为真的情况下模糊图像,则应使用类似的方法

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

However, you may want to change how the mask has been generated, as currently it will only blur the orange and white parts of the fish. 但是,您可能要更改蒙版的生成方式,因为当前它只会使鱼的橙色和白色部分模糊。

Here is an answer that works on a Vec3b but only looks at channel 0. It respects the mask and only blurs where there is not a mask.这是一个适用于 Vec3b 但仅查看通道 0 的答案。它尊重蒙版,仅在没有蒙版的地方模糊。 This prevents "halo" effects on the edges of interior masked areas.这可以防止内部遮罩区域边缘出现“光晕”效应。 In my case it is a ball with the outside of circle masked out and also the glare spot reflected off the ball.在我的情况下,它是一个球,圆的外部被遮住了,而且眩光点也从球上反射出来。

    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