I'm using yolo v8 to detect subjects in pictures. It's working well, and can create quite precise masks over subjects.
from ultralytics import YOLO
model = YOLO('yolov8x-seg.pt')
for output in model('image.jpg', return_outputs=True):
for segment in output['segment']:
print(segment)
The code above works, and generates a series of "segments", which are a list of points that define the shape of subjects on my image. That shape is not convex (for example horses).
I need to figure out if a random coordinate on the image falls within these segments, and I'm not sure how to do it.
My first approach was to build an image mask using PIL. That roughly worked, but it doesn't always work, depending on the shape of the segments. I also thought about using shapely, but it has restrictions on the Polygon classes, which I think will be a problem in some cases.
In any case, this really feels like a problem that could easily be solved with the tools I'm already using (yolo, pytorch, numpy...), but to be honest I'm too new to all this to figure out how to do it properly.
Any suggestion is appreciated :)
You should be able to get a segmentation mask from your model: imagine a binary image where black (zeros) represents the background and white (or other non zero values) represent an instance of a segmentation class.
Once you have the binary image you can use opencv's findContours function to get a the largest outer path.
Once you have that path you can use pointPolygonTest() to check if a point is inside that contour or not.
Related
I have a set of images that look like this:
Using python need a way to find a contour around the yellow shape that ignores the isolated points and is not too complex. Something looking a bit like this :
I tried some methods such as the find_contours function from skimage,which gives this after keeping only the biggest contour:
which is not what I am looking for. A also tried active contour (snake) which had the problem of paying too much attention to isolated pixels. Is there a particular method that would help me in this situation ?
Thank you
Assuming the yellow blob is slightly different across your images, I recommend you look into either using Morphological Operations, or using Contour Approximation.
I've never used scikit-image, but it appears to have Morphological functionalities included.
You can take a look at this OpenCV tutorial for a quick guideline of the different operations.
But I think all you need is to use the "Opening" operation to preprocess your yellow shape; making it smoother and removing the random speckles.
Another approach is by approximating that contour you've extracted to make it smoother. For scikit-image, that is the measure.approximate_polygon function. Also another OpenCV tutorial for reference on how Contour Approximation works (the same algorithm as with scikit-image).
Forgive me but I'm new in OpenCV.
I would like to delete the common background in 3 images, where there is a landscape and a man.
I tried some subtraction codes but I can't solve the problem.
I would like output each image only with the man and without landscape
Are there in OpenCV Algorithms what do this do? (then without any manual operation so no markers or other)
I tried this python code CV - Extract differences between two images
but not works because in my case i don't have an image with only background (without man).
I thinks that good solution should to Compare all the images and save those "points" that are the same at least in an image.
In this way I can extrapolate a background (which we call "Result.jpg") and finally analyze each image and cut those portions that are also present in "Result.jpg".
You say it's a good idea? Do you have other simplest ideas?
Without semantic segmentation, you can't do that.
Because all you can compute is where two images differ, and this does not give you the silhouette of the person, but an overlapping of two silhouettes. You'll never know the exact outline.
I am new to python and opencv. I am analysing images of clouds, and I need to remove the buildings, so that the subsequent analysis will have less noise. I tried using Canny edge detection and then fill in the contours, but did not get too far. I also tried thresholding by pixel colours, but cannot reliably exclude just the buildings and not other parts of the image containing the clouds.
Is there a way I can efficiently and accurately remove the buildings and keep all of the clouds/sky? Thanks for the tips in advance.
You could use a computer vision model that finds the buildings. There may be some open source ones out there. The only one I can think of at the moment is this semantic segmentation model. There should be details on how to implement it, but there could definitely be others out there.
https://github.com/CSAILVision/semantic-segmentation-pytorch
I think one of the classes is buildings and you could theoretically run the model and get the dimensions of the building and take it out.
I'm a beginner in opencv using python. I have many 16 bit gray scale images and need to detect the same object every time in the different images. Tried template matching in opencv python but needed to take different templates for different images which could be not desirable. Can any one suggest me any algorithm in python to do it efficiently.
Your question is way too general. Feature matching is a very vast field.
The type of algorithm to be used totally depends on the object you want to detect, its environment etc.
So if your object won't change its size or angle in the image then use Template Matching.
If the image will change its size and orientation you can use SIFT or SURF.
If your object has unique color features that is different from its background, you can use hsv method.
If you have to classify a group of images as you object,for example all the cricket bats should be detected then you can train a number of positive images to tell the computer how the object looks like and negative image to tell how it doesn't, it can be done using haar training.
u can try out sliding window method. if ur object is the same in all samples
One way to do this is to look for known colors, shapes, and sizes.
You could start by performing an HSV threshold on your image, by converting your image to HSV colorspace and then calling
cv2.inRange(source, (minHue, minSat, minVal), (maxHue, maxSat, maxVal))
Next, you could use cv2.findContours to find all the areas in your image that meet your color requirements. Then, you could use methods such as boundingRect and contourArea to find specific attributes of the object that you want.
What you will end up with is essentially a 'pipeline' that can take a frame, and look for a shape that fits the criteria you have set. Depending on the complexity of what you want to do (you didn't say what you're looking for), this may or may not work, but I have used it with reasonable success.
GRIP is an application that allows you to threshold things in a visual way, and it will also generate Python code for you if you want. I don't really recommend using the generated code as-is because I've run into some problems that way. Here's the link to GRIP: https://github.com/WPIRoboticsProjects/GRIP
If the object you want to detect has different size in every image and also slightly varies in shape too, then I recommend you use HaarCascade of that object. If the object is very general then you can easily find haar cascade for it online. Otherwise it is not very difficult to make haar cascades(can be a littile time consuming though).
You can use this tutorial by sentdex to make HaarCascade here.
Or If you want to know how to use HaarCascades then you can get it on this link
here.
I use OpenCV 2.4.8 in python to segment images and find objects.
I want to use findContours to list the objects and analyse their area, shape and so on. But if I have two objects that are only separated by a thin (1 px wide) diagonal line or even only diagonally touch at the corners, they will be recognised as one object.
This image illustrates the problem:
There are obviously two objects, but they are recognised as one.
In Matlab one can specify a connectivity parameter (neighbourhood of 4 or 8) to solve this problem. Can this also be done in some way using opencv? Maybe using the hierarchy of the contours or some other work around?
I know, that I could use morphological erosion or opening to separate the two objects, but this can cause problems in other parts of my image. I already tried this.
If your objects are circular, you can try using circular Hough transform.
If such an image is represented as a single contour, then it is bound to have defects. You can search for convexity defects and proceed from there. But this again depends on the objects in your image.
I'm not sure what kind of objects your image contains, so its hard to come to a definitive answer.