Home > Enterprise >  OpenCV: return only selected area of an image and return the rest as black
OpenCV: return only selected area of an image and return the rest as black

Time:10-18

I'm trying to select a certain area of an image, and it's already successful. However, there's another problem, the selected area is not in the same place as the source image. Here's the visualization about it:

The left image is the area that I generate. But it's not in the right place as I wanted in the right image.

Here's a simple code that I tried already:

import cv2
import NumPy as np

pic= cv2.imread('set.jpeg')
pic = cv2.resize(pic, dsize=(500, 400), interpolation=cv2.INTER_CUBIC)
gray=cv2.cvtColor(pic,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),5)
_,thres = cv2.threshold(blur, 100,250, cv2.THRESH_TOZERO)
res = cv2.Canny(thres, 100, 200, L2gradient=True)

circles = cv2.HoughCircles(res,cv2.HOUGH_GRADIENT,1,20,param1=200,param2=15,minRadius=80,maxRadius=100)

crops = []
for i in circles[0,:]:
    # draw the outer circle
    cv2.circle(pic,(int(i[0]),int(i[1])),int(i[2]),(255,255,255),2)
    i = i.astype(int)
    crop = res[i[1]-i[2]:i[1] i[2], i[0]-i[2]:i[0] i[2]]
    crop = np.pad(crop,[(101, ), (151, )], mode='constant')
    crops.append(crop)

result = np.concatenate((crops[0],res),axis=1)
cv2.imshow('Hole',result)

cv2.waitKey(0)
cv2.destroyAllWindows()

I want the result like the right image (generate the blue box image only) and return the rest as black (like the left image).

Is there any way to get the result in the right place as I wanted? (Like the right image) Thank you!!

CodePudding user response:

The issue has been solved by creating masks and combine the foreground and background by these lines of code:

import cv2
import numpy as np

pic= cv2.imread('Assets/set.jpeg')
pic = cv2.resize(pic, dsize=(500, 400), interpolation=cv2.INTER_CUBIC)
gray=cv2.cvtColor(pic,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),5)
_,thres = cv2.threshold(blur, 100,250, cv2.THRESH_TOZERO)
res = cv2.Canny(thres, 100, 250, L2gradient=True)

circles = cv2.HoughCircles(res,cv2.HOUGH_GRADIENT,1,20,param1=200,param2=15,minRadius=80,maxRadius=100)
circles = np.uint16(np.around(circles))

mask = np.full((res.shape[0], res.shape[1]), 1, dtype=np.uint8)  # mask is only 
clone = pic.copy()
for i in circles[0, :]:
    cv2.circle(mask, (i[0], i[1]), i[2], (255, 255, 255), -1)
    cv2.circle(clone, (i[0], i[1]), i[2], (255, 255, 255), 1)

# get first masked value (foreground)
fg = cv2.bitwise_or(res, res, mask=mask)

# get second masked value (background) mask must be inverted
mask = cv2.bitwise_not(mask)
background = np.full(res.shape, 255, dtype=np.uint8)
bk = cv2.bitwise_or(background, background, mask=mask)

# combine foreground background
final = cv2.bitwise_or(fg, bk)

result = np.concatenate((res,final),axis=1)
cv2.imshow('Hole',result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Nothing to be asked anymore and I will close the question. Thank you!!

  • Related