How do ı make the image I've masked smoother? I want to remove the little white pixels from the second picture, and I want to throw some of the masked places out of the picture, how can I do that?
import cv2
import numpy as np
img = cv2.imread("colors.jpg")
height,width = 720,720
img = cv2.resize(img,(width,height))
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
lower_range = np.array([100,50,50])
upper_range = np.array([150,255,255])
mask = cv2.inRange(hsv, lower_range, upper_range)
#res = cv2.bitwise_and(img,img, mask=mask)
cv2.imshow("Image",img)
cv2.imshow("Mask",mask)
#cv2.imshow("res",res)
cv2.waitKey(0)
cv2.destroyAllWindows
Try using the closing and opening concept of computer vision. You need is erosion in your case to get rid of the tiny white dots.
There are two things that can controlled for the resultant outcome as per your requirement i.e. kernel size and iterations.
Here is the code is I could reproduce and provide a near solution.
import numpy as np
img = cv2.imread("colors.jpg")
height,width = 720,720
img = cv2.resize(img,(width,height))
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
lower_range = np.array([100,50,50])
upper_range = np.array([150,255,255])
kernel = np.ones((5,5),np.uint8)
mask = cv2.inRange(hsv, lower_range, upper_range)
erosion = cv2.erode(mask,kernel,iterations = 1)
#res = cv2.bitwise_and(img,img, mask=mask)
cv2.imshow("Image",img)
cv2.imshow("Mask",erosion)
#cv2.imshow("res",res)
cv2.waitKey(0)
cv2.destroyAllWindows
import cv2
import numpy as np
img = cv2.imread("colors.jpg")
height,width = 720,720
img = cv2.resize(img,(width,height))
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
lower_range = np.array([100,50,50])
upper_range = np.array([150,255,255])
kernel = np.ones((5,5),np.uint8)
mask = cv2.inRange(hsv, lower_range, upper_range)
erosion = cv2.erode(mask,kernel,iterations = 1)
#res = cv2.bitwise_and(img,img, mask=mask)
cv2.imshow("Image",img)
cv2.imshow("Mask",erosion)
#cv2.imshow("res",res)
cv2.waitKey(0)
cv2.destroyAllWindows
Result:
Related
I extracted green color in image with cv2.inRange().
But, The colors of the extracted images were all different.
like this --> enter image description here
I want to change extracted image's color to same.
Please help me....
This is my code.
import numpy as np
import cv2
img = cv2.imread('test_img.jpg')
height, width = img.shape[:2]
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_green = (35,45,0,0)
upper_green = (80, 255, 255,0)
img_mask = cv2.inRange(img_hsv, lower_green, upper_green)
img_result = cv2.bitwise_and(img, img, mask = img_mask)
cv2.imshow('color',img_result)
Output
enter image description here
You need to zero the B and R dimensions of the image, as follows:
import numpy as np
import cv2
img = cv2.imread('test_img.jpg')
height, width = img.shape[:2]
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_green = (35,45,0,0)
upper_green = (80, 255, 255,0)
img_mask = cv2.inRange(img_hsv, lower_green, upper_green)
img_result = cv2.bitwise_and(img, img, mask = img_mask)[:, :, 1]
img[:, :, 0] = 0
img[:, :, 2] = 0
img[:, :, 1] = img_result
cv2.imshow('color', img)
cv2.waitKey(0)
or if you want a simpler way to output the image, you can use the matplotlib.pyplot, as follows:
import matplotlib.pyplot as plt
plt.imshow(img)
Cheers
So i'm having a problem with removing green background and replacing it, . I have this black box in a green background. When i replaced it with np.where(pixel == 0), the program chooses the black box and the mask to replace with another background. How do i fix this problem?
Here's my code:
import cv2
import numpy as np
frame = cv2.imread("black_box.jpg")
back_ground= cv2.imread("back_ground.jpg")
if back_ground.shape != frame.shape:
back_ground = cv2.resize(back_ground,(frame.shape[1],frame.shape[0]))
hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
lower_green = np.array([42, 180, 39])
green = np.array([81,255,255])
mask = cv2.inRange(hsv,lower_green,green)
mask_inv = cv2.bitwise_not(mask)
fg = cv2.bitwise_and(frame,frame, mask = mask_inv)
fg = np.where(fg == 0,back_ground,fg)
cv2.imshow("fg",fg)
cv2.waitKey(0)
I think there are some confusion on what your image is and what your background is. You apply the hsv conversion to the black and green image to detect the green then you do a bitwise_and mask with that mask and the same input image.
My code below gives, I believe, what you are after.
import cv2
import numpy as np
frame = cv2.imread("im2.png")
back_ground= cv2.imread("im1.png")
if back_ground.shape != frame.shape:
back_ground = cv2.resize(back_ground,(frame.shape[1],frame.shape[0]))
hsv = cv2.cvtColor(back_ground,cv2.COLOR_BGR2HSV)
lower_green = np.array([42, 180, 39])
green = np.array([81,255,255])
mask = cv2.inRange(hsv,lower_green,green)
mask_inv = cv2.bitwise_not(mask)
fg = cv2.bitwise_and(frame,frame, mask = mask)
fg_inv = cv2.bitwise_and(frame,frame, mask = mask_inv)
#fg = np.where(fg == 0,back_ground,fg) - unnecessary
cv2.imshow("mask", mask)
cv2.imshow("fg", fg)
cv2.imshow("mask_inv", mask_inv)
cv2.imshow("fg_inv", fg_inv)
cv2.waitKey(0)
I tried a code from stackoverflow but it shows black color for me. what I want to do is:
Get Tomatoes white and other things black of this image
To get red colors out of this image I used this code:
import cv2
import numpy as np
img = cv2.imread('test.png')
img = np.copy(img)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_red = np.array([217, 25, 0])
upper_red = np.array([254, 217, 196])
mask = cv2.inRange(hsv, lower_red, upper_red)
#mask = cv2.bitwise_not(mask)
cv2.imwrite('mask.png', mask)
cv2.destroyAllWindows()
result is this
thank you for reading
The following adaptation from your code:
import cv2
import numpy as np
img = cv2.imread('test2.png')
img = np.copy(img)
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
lower_red = np.array([225, 0, 0])
upper_red = np.array([255, 200, 200])
mask = cv2.inRange(rgb, lower_red, upper_red)
cv2.imwrite('mask.png', mask)
cv2.destroyAllWindows()
produces this output:
I simply removed the conversion to HSV (which is not necessary and I guess your initial lower and upper limits where thought to be for RGB anyway?). I played around a bit with the limits, but I guess, if you tinker a bit more with them, you can get better results.
Try this HSV mask:
import cv2
import numpy as np
img = cv2.imread("tomato.jpg")
lower = np.array([0, 55, 227])
upper = np.array([21, 255, 255])
mask = cv2.inRange(cv2.cvtColor(img, cv2.COLOR_BGR2HSV), lower, upper)
cv2.imshow("Image", mask)
cv2.waitKey(0)
Output:
I am trying to remove the background of the image (the background can be any other color or contain noise, dust, etc)
This is the image:
And this is my code:
import cv2
img = cv2.imread('image.jpg', 0)
norm_img = np.zeros(img.shape)
normim = cv2.normalize(img, norm_img, 0, 255, cv2.NORM_MINMAX)
_, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(thresh1, cv2.MORPH_OPEN, kernel)
mask_inv = cv2.bitwise_not(opening)
seg = cv2.add(mask_inv, normim)
Output:
The code is about to normalize the original image then add with the image that applied morphological which is a binary image.
Result of normalizing the original image and applying morphological the original image:
So what happens with my code, how can I remove the background?
You can do that using Numpy and Python/OpenCV as follows:
Input:
Mask:
import cv2
import numpy as np
# read image
img = cv2.imread('fingerprint.jpg')
# read mask as grayscale
mask = cv2.imread('mask.jpg', cv2.IMREAD_GRAYSCALE)
# threshold mask
thresh = cv2.threshold(mask, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# apply mask to image
result = img.copy()
result[thresh==0] = (255,255,255)
# save results
cv2.imwrite('fingerprint_masked.jpg', result)
cv2.imshow('masked image', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result:
You can try use percentile for normalization.
import cv2
from numpy import percentile
img = cv2.imread('mSEsr.jpg', cv2.IMREAD_GRAYSCALE)
cv2.normalize(img, img, 0, 255, cv2.NORM_MINMAX)
lower=percentile(img, 5)
upper=percentile(img,50)
cv2.normalize(img, img, -lower, 255+255-upper, cv2.NORM_MINMAX) # tune parameters
cv2.imwrite('finger_norm.png', img)
Result:
I may be overshooting a bit but I'm trying to use a mask generated from my image and subtract it from the main image. I'm quite open to instead extracting the characters but am not sure how to collect the entire blue sample, I haven't that correct balance yet.
The page here demonstrates the inverse of what I'm trying to achieve.
Base image
The mask utilizing hsv bounds then inverting it to show it better
Darkening it
I wish to now take that mask and remove it from the main image.
import cv2
import numpy as np
import random as rng
from PIL import Image
from PIL import ImageOps
from utils import helper
image_name = 'capt13.jpg'
img = cv2.imread(image_name)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_red = np.array([0,120,70])
upper_red = np.array([10,255,255])
lower_mask = cv2.inRange(hsv, lower_red, upper_red)
lower_red = np.array([160,120,70])
upper_red = np.array([180,255,255])
upper_mask = cv2.inRange(hsv, lower_red, upper_red)
'''
lower_blue = np.array([80,40,30])
upper_blue = np.array([140,255,255])
lower_mask = cv2.inRange(hsv, lower_blue, upper_blue)
lower_blue = np.array([240,220,200])
upper_blue = np.array([360,255,255])
upper_mask = cv2.inRange(hsv, lower_blue, upper_blue)
'''
mask = lower_mask + upper_mask
res_lines = cv2.bitwise_and(img,img, mask= mask)
# Keep the inverted
image = Image.fromarray(res_lines)
image.save('res.png')
inverted = ImageOps.invert(image)
inverted = inverted.convert('L')
inverted.save('inverted.png')
binary = np.array(inverted)
for row in range(len(binary)):
for col in range(len(binary[row])):
if binary[row][col] != 255:
binary[row][col] = 0
binary_image = Image.fromarray(binary)
binary_image.save('binary.png')
Extracting the Blue (As stated above that I'm open to a better solution for this)
The mask utilizing hsv bounds then inverted it
Darkening it
Straight subtraction works, provided both images are the same size:
im = cv2.imread("image.png")
mask = cv2.imread("mask.png")
diff_im = im - im2
Alternatively, you can use OpenCV's built in subtract, which does an element-wise subtraction:
diff_im = cv2.subtract(im, im2)
As a final thought, you should also try absdiff, as it will convert negative results to zeroes, which may be what you want.
diff_im = cv2.absdiff(im, im2)