I do not know openCV but I would like to know
Area extraction
If the white area is reduced by hsv, the text is broken and can not be recognised. If there is a white area, THRESH_BINARY_INV is converted as shown above.
I would appreciate your help.
I set out to solve this problem.
I do not know if this is being interpreted properly.
My code will be attached below
import cv2
import numpy as np
def tracking():
frame = cv2.imread('test4.png')
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([255, 255, 240])
mask = cv2.inRange(hsv, lower, upper)
res2 = cv2.bitwise_and(frame, frame, mask=mask)
cv2.imshow('asdasd2', res2)
_, edge2 = cv2.threshold(res2, 100, 255, cv2.THRESH_BINARY_INV)
cv2.imshow('asdasd2', edge2)
cv2.imshow('original', frame)
cv2.imshow('finish', res2)
cv2.waitKey(0)
cv2.destroyAllWindows()
tracking()
Related
I have some images which are in form of a grid. I have a code that works to find the largest rectangle in the grid. However it works in some images and completely fails in doing so in others, I need help fine-tuning the code to work in all the cases. Ideally I'd like the contours exactly on the border.
The code:
import cv2
import numpy as np
img = cv2.imread('3.jpg')
frame = cv2.resize(img,(1000,500))
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_red = np.array([0, 10, 120])
upper_red = np.array([15, 255, 255])
mask = cv2.inRange (hsv, lower_red, upper_red)
cv2.imshow("a",mask)
cv2.waitKey(0)
contours, _ = cv2.findContours(mask.copy(),
cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
if len(contours) > 0:
red_area = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(red_area)
cv2.rectangle(frame,(x, y),(x+w, y+h),(0, 0, 255), 2)
cv2.imshow('frame', frame)
cv2.imshow('mask', mask)
cv2.waitKey(0)
Image in which it works correctly:
Image in which the code does not work:
your problem in finding the max contour after thresolding can be solved simply by identifying the max contour corners:
import cv2
import numpy as np
img = cv2.imread('2.png')
frame = cv2.resize(img,(1000,500))
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_red = np.array([0, 10, 120])
upper_red = np.array([15, 255, 255])
mask = cv2.inRange (hsv, lower_red, upper_red)
y0 = np.min(np.where(mask>0)[0])
x0 = np.min(np.where(mask>0)[1])
y1 = np.max(np.where(mask>0)[0])
x1 = np.max(np.where(mask>0)[1])
cv2.rectangle(frame,(x0, y0),(x1, y1),(0, 0, 255), 2)
cv2.imshow('frame', frame)
cv2.imshow('mask', mask)
cv2.waitKey(0)
I have below preprocessed rice image. I want to fill the rice with black color and then perform the inverse operation to find contours. I am trying to use Erosion/Dilation operation but not working. Below is the code snippet I am using.
First I used shadow removal algorithm then used adaptive thresholding which gives the Input image. Now, I want to change the Input image to the output image.
Original Image:
Input Image:
Required Output Image:
Code Snippet:
oposite = cv2.bitwise_not(img)
#Erosion
kernel = np.ones((3,3),np.uint8)
erosion = cv2.dilate(des,kernel,iterations = 1)
erosion = cv2.bitwise_not(erosion)
im_out = oposite + erosion
cv2.imshow("output", im_out)
cv2.waitKey(0)
You can create an HSV mask by using the cv2.COLOR_BGR2HSV flag in the cv2.cvtColor() method, and by using the cv2.inRange() method. I basically changed the maximum saturation value from 255 to 100:
import cv2
import numpy as np
img = cv2.imread("rice.jpg")
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([179, 100, 255])
mask = cv2.inRange(img_hsv, lower, upper)
cv2.imshow("Mask", mask)
cv2.waitKey(0)
Output:
If you're looking to make the grains thinner, you can turn down the maximum hue value, from 179 to, say,111, along with the maximum saturation value at 100:
import cv2
import numpy as np
img = cv2.imread("rice.jpg")
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([111, 100, 255])
mask = cv2.inRange(img_hsv, lower, upper)
cv2.imshow("Mask", mask)
cv2.waitKey(0)
Output:
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 would like to detect this gate below, ideally the entire gate. I have played around for hours with a trackbar script but I am just not finding the right color space. I found other threads that just track yellow and not even that is working.. This is my code:
def track():
cap = cv2.VideoCapture('../files/sub/gate_mission1.mp4')
while True:
_, frame = cap.read()
cv2.imshow('img', frame)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower = np.array([20, 93, 0])
upper = np.array([45, 255, 255])
mask = cv2.inRange(hsv, lower, upper)
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(frame, contours, -1, (0, 255, 0), 2)
Maybe there is a way to just remove all the blue/greenish too im not sure? What are my options here?
This seems to work for me by thresholding in LAB colorspace in Python/OpenCV. According to Wikipedia at https://en.wikipedia.org/wiki/CIELAB_color_space "The a* axis is relative to the green–red opponent colors, with negative values toward green and positive values toward red." So we ought to get reasonably good separation for your green and reddish colors.
Input:
import cv2
import numpy as np
# load images
img = cv2.imread('gate.jpg')
# convert to LAB
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
# set black ranges
lower = (130,105,100)
upper = (170,170,160)
# threshold on black
result = cv2.inRange(lab, lower, upper)
# save output
cv2.imwrite('gate_thresh.jpg', result)
# display results
cv2.imshow('thresh',result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Threshold Image
I am trying to remove text from images that has a black border with white fill. Take the image below as an example.
I have tried a few options utilizing opencv and skimage inpaint
import cv2
from skimage.restoration import inpaint
img = cv2.imread('Documents/test_image.png')
mask = cv2.threshold(img, 210, 255, cv2.THRESH_BINARY)[1][:,:,0]
dst = cv2.inpaint(img, mask, 7, cv2.INPAINT_TELEA)
image_result = inpaint.inpaint_biharmonic(img, mask,
multichannel=True)
cv2.imshow('image',img)
cv2.imshow('mask',mask)
cv2.imshow('dst',dst)
cv2.imshow('image_result',image_result)
cv2.waitKey(0)
It seems like the inpainting is just trying to fill with black as that is what it is identifying as being around the areas of interest. What I would like to do is remove the white text and black borders completely, or secondarily try to fill the white with more information from surrounding colors than just the black.
Here is the best solution I could come up with, still open to others with more experience showing me a better way if anyone has an idea.
mask = cv2.threshold(img, 245, 255, cv2.THRESH_BINARY)[1][:,:,0]
new_mask = cv2.dilate(mask, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10,10)))
dst = cv2.inpaint(img, new_mask, 7, cv2.INPAINT_TELEA)
Here are two inpainting methods in Python/OpenCV. Note that I use the saturation channel to create the threshold, since white and black have zero saturation, in principle.
Input:
import cv2
import numpy as np
# read input
img = cv2.imread('white_black_text.png')
# convert to hsv and extract saturation
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
sat = hsv[:,:,1]
# threshold and invert
thresh = cv2.threshold(sat, 10, 255, cv2.THRESH_BINARY)[1]
thresh = 255 - thresh
# apply morphology dilate
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15,15))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_DILATE, kernel)
# do inpainting
result1 = cv2.inpaint(img,thresh,11,cv2.INPAINT_TELEA)
result2 = cv2.inpaint(img,thresh,11,cv2.INPAINT_NS)
# save results
cv2.imwrite('white_black_text_threshold.png', thresh)
cv2.imwrite('white_black_text_inpainted1.png', result1)
cv2.imwrite('white_black_text_inpainted2.png', result1)
# show results
cv2.imshow('thresh',thresh)
cv2.imshow('result1',result1)
cv2.imshow('result2',result2)
cv2.waitKey(0)
cv2.destroyAllWindows()
Threshold and morphology cleaned result:
Result 1 (Telea):
Result 2 (Navier Stokes):