How to find the subimage in a large image using python cv2 - python

sample - 1
sample - 2
I have a image with sub-images inside how to find the sub-images in a main image without template method and using python code or is there any software to find the sub-image.
The sample -2 image it have 1 sub-image in it how to find it.
import cv2
# Load the image
image = cv2.imread("img_2.jpg")
# Define the callback function for the threshold slider
def threshold_callback(threshold):
# Perform Canny edge detection
edges = cv2.Canny(image, threshold, threshold*2)
# Display the edges
cv2.imshow("Edges", edges)
# Create a window to display the original image
cv2.namedWindow("Original", cv2.WINDOW_NORMAL)
cv2.imshow("Original", image)
# Create a trackbar for adjusting the threshold
cv2.createTrackbar("Threshold", "Original", 0, 255, threshold_callback)
# Wait for the user to press a key
cv2.waitKey(0)
# Close all windows
cv2.destroyAllWindows()
i try this but it not working.

Related

Find specific contours within image (Python OpenCV)

I have a script that loads an image and using selectROI() allows me to select and crop a specific part of that image and get the contours of just that part alone. But how can I search if are there any other contours in the original image just like the one I selected and cropped? My goal is to teach a shape and verify if that shape occurs in any other parts of that image or any other image that I load after, hopefully even being able to have a certain tolerance of correspondence.
I could try something like object detection using HAAR Cascade or YOLO, but I am positive that there is a way to do it without relying on heavy-weight computation AI models, especially because I want to use it on static images, not on video. I say that because that is how it is made on industrial vision systems. You only need to load a single image and select the object that you want to detect so the contours can be drawn. We you load another image, the software will look for these contours up to a certain level of correspondence.
import cv2 as cv
import numpy as np
# Load Image
img = cv.imread('C:/Users/ALEMAC/Downloads/geometricShapes.jpg')
#Selecting ROI
imgdraw = cv.selectROI(img)
cropimg = img[int(imgdraw[1]):int(imgdraw[1]+imgdraw[3]), int(imgdraw[0]):int(imgdraw[0]+imgdraw[2])] #displaying the cropped image as the output on the screen
cv.imshow('Cropped_image',cropimg)
blank = np.zeros(cropimg.shape[:2], dtype='uint8') # creates a blank img, with the same size as our geometricShapes img
gray = cv.cvtColor(cropimg, cv.COLOR_BGR2GRAY)
blur = cv.GaussianBlur(gray,(3,3), cv.BORDER_DEFAULT)
# Find edges using contours method
ret, thresh = cv.threshold(blur, 125,255, cv.THRESH_BINARY)
#cv.imshow('Thresh', thresh)
contours, hierachies = cv.findContours(thresh, cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
cv.drawContours(blank,contours,-1,(255,255,255),thickness=1)
cv.imshow('Contours', blank)
cv.waitKey(0)

How to do interactive image binarization using trackbars?

I have a code which gives me binary images using Otsu thresholding. I am making a dataset for a U-Net, and I want to try different algorithms (global as well as local) for the same, so that I can save the "best" image. Below is the code for my image binarization.
import cv2
import numpy as np
import skimage.filters as filters
img = cv2.imread('math.png') # read the image
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # convert to gray
smooth = cv2.GaussianBlur(gray, (95,95), 0) # blur
division = cv2.divide(gray, smooth, scale=255) # divide gray by morphology image
# Add Morphology here. Dilation, Erosion, Opening, Closing or so.
sharp = filters.unsharp_mask(division, radius=1.5, amount=1.5, multichannel=False, preserve_range=False) # sharpen using unsharp masking
sharp = (255*sharp).clip(0,255).astype(np.uint8)
thresh = cv2.threshold(sharp, 0, 255, cv2.THRESH_OTSU )[1] # threshold
I am getting pretty decent results with a broader area, but I want to use cv2.namedWindow, cv2.createTrackbar, cv2.getTrackbarPos, so that I can set the values of radius, amount, kernel, dilation, erosion, etc. by using below functions.
cv2.namedWindow('Tracking Window')
cv2.createTrackbar('param1','Tracking Window',0,255,dummy) # dummy is just a dummy function which returns None
param1 = cv2.getTrackbarPos('param1','Tracking Window')
How can I get all those. Also, how can I save the image when I press s, open next image by pressing n?
Original Question was posted by me 6 months ago
The code of my solution got longer than expected, but it offers some fancy manipulation possibilities. First of all, let's the see the actual window:
There are sliders for
the morphological operation (dilate, erode, close, open),
the structuring element (rectangle, ellipse, cross), and
the kernel size (here: limited to the range 1 ... 21).
The window name reflects the current settings for the first two sliders:
When pressing s, the image is saved incorporating the current settings:
Saved image as Erosion_Ellipsoid_SLEM_11.png.
When pressing n, the next image from a list is selected.
At any time, when pressing q, the application is exited. It ends automatically after processing all images from the list.
Before and after the interactive part, you can add any operation you want, cf. the code.
And, here's the full code:
import cv2
# Collect morphological operations
morphs = [cv2.MORPH_DILATE, cv2.MORPH_ERODE, cv2.MORPH_CLOSE, cv2.MORPH_OPEN]
# Collect some texts for later
morph_texts = {
cv2.MORPH_DILATE: 'Dilation',
cv2.MORPH_ERODE: 'Erosion',
cv2.MORPH_CLOSE: 'Closing',
cv2.MORPH_OPEN: 'Opening'
}
# Collect structuring elements
slems = [cv2.MORPH_RECT, cv2.MORPH_ELLIPSE, cv2.MORPH_CROSS]
# Collect some texts for later
slem_texts = {
cv2.MORPH_RECT: 'Rectangular SLEM',
cv2.MORPH_ELLIPSE: 'Ellipsoid SLEM',
cv2.MORPH_CROSS: 'Cross SLEM'
}
# Collect images
images = [...]
# Set up maximum values for each slider
max_morph = len(morphs) - 1
max_slem = len(slems) - 1
max_ks = 21
# Set up initial values for each slider
morph = 0
slem = 0
ks = 1
# Set up initial working image
temp = None
# Set up initial window name
title_window = 'Interactive {} with {}'.format(morph_texts[morphs[morph]],
slem_texts[slems[slem]])
# Triggered when any slider is manipulated
def on_trackbar(unused):
global image, ks, morph, slem, temp, title_window
# Get current slider values
morph = cv2.getTrackbarPos('Operation', title_window)
slem = cv2.getTrackbarPos('SLEM', title_window)
ks = cv2.getTrackbarPos('Kernel size', title_window)
# Reset window name
cv2.setWindowTitle(title_window, 'Interactive {} with {}'.
format(morph_texts[morphs[morph]],
slem_texts[slems[slem]]))
# Get current morphological operation and structuring element
op = morphs[morph]
sl = cv2.getStructuringElement(slems[slem], (ks, ks))
# Actual morphological operation
temp = cv2.morphologyEx(image.copy(), op, sl)
# Show manipulated image with current settings
cv2.imshow(title_window, temp)
# Iterate images
for image in images:
# Here go your steps before the interactive part
# ...
image = cv2.threshold(cv2.cvtColor(image.copy(), cv2.COLOR_BGR2GRAY),
0, 255, cv2.THRESH_OTSU)[1]
# Here starts the interactive part
cv2.namedWindow(title_window)
cv2.createTrackbar('Operation', title_window, morph, max_morph, on_trackbar)
cv2.createTrackbar('SLEM', title_window, slem, max_slem, on_trackbar)
cv2.createTrackbar('Kernel size', title_window, ks, max_ks, on_trackbar)
cv2.setTrackbarMin('Kernel size', title_window, 1)
on_trackbar(0)
k = cv2.waitKey(0)
# Exit everytime on pressing q
while k != ord('q'):
# Save image on pressing s
if k == ord('s'):
# Here go your steps after the interactive part, but before saving
# ...
filename = '{} {} {}.png'.\
format(morph_texts[morphs[morph]],
slem_texts[slems[slem]],
ks).replace(' ', '_')
cv2.imwrite(filename, temp)
print('Saved image as {}.'.format(filename))
# Go to next image on pressing n
elif k == ord('n'):
print('Next image')
break
# Continue if any other key was pressed
k = cv2.waitKey(0)
# Actual exiting
if k == ord('q'):
break
Hopefully, the code is self-explanatory. If not, don't hesitate to ask questions. You should be able to easily add every slider you additionally need by yourself, e.g. for the filters.unsharp_mask stuff.
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
OpenCV: 4.5.1
----------------------------------------

Opencv Python3 when attempting to switch from saved images to live video feed the program hangs

Hello there people of the internet,
The code in question is using python 3.8.5 and opencv 4 (I do not know how to check the exact version but I know its opencv 4). My team and I are attempting to take a live video feed from a usb webcam and determine the distance between the camera and the object in the video feed. We had some success in reading the distance with image stills taken from the same camera and read via the imutils library. But now we want to attempt to calculate that data live.
Our code is below.
from imutils import paths
import numpy as np
import imutils
import cv2
import time
import os
def find_marker(image):
#conver the image into grayscales, blurs it then detects edges
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 35, 125)
#find the contours in the edged image and keep the largest one;
#w'll assume that this our piece of paper in the image
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key = cv2.contourArea)
#compute the bounding box of the paper region and return it
return cv2.minAreaRect(c)
def distance_to_camera(knownWidth, focalLength, perWidth):
#compute and return the distance from the marker to the camera
return (knownWidth * focalLength) / perWidth
#intialize the known distances from the camera to the object
KNOWN_DISTANCE = 22
#initialize the known object width, which in this case the piece of paper is 12 inches
KNOWN_WIDTH = 11
#load the first image that contains an object that is known to be 2 feet
#from our camera, the find the paper marker in the image and
#initialize the focal length
rootimage = cv2.imread("/Volumes/404/final_rov_code/Python/images/2ft.jpg")
marker1 = find_marker(rootimage)
marker2 = marker1[0][1] - marker1[1][1]
focalLength = (marker2 * KNOWN_DISTANCE) / KNOWN_WIDTH
print(marker1)
print(marker2)
image = cv2.VideoCapture(0)
#Loop over the image
while True:
#load the image, find the marker in the image then compute the
#distance to the marker from the camera
frame, ret = image.read()
marker = find_marker(ret)
inches = distance_to_camera(KNOWN_WIDTH, focalLength, marker[1][0])
print(inches)
#draw a bounding box around the image and display it
box = cv2.cv.BoxPoints(marker) if imutils.is_cv2() else cv2.boxPoints(marker)
box = np.int0(box)
cv2.drawContours(frame, [box], -1, (0, 255, 0), 2)
cv2.putText(ret, "%.2fin" % inches,
(ret.shape[1] - 200, ret.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX,
2.0, (0, 255, 0), 3)
cv2.imshow("image", ret)
# if cv2.waitKey(33) == ord('q'):
# os.system('pause')
I understand that it should be as minimalistic as possible but since we have no idea what could be causing the program to hang upon reading the first frame of the video feed. Could it be the fact that the processing is taking too many resources from the single thread? (We're all newbies to the advanced sides of opencv and python 3)
There is no other errors that we are aware of at the moment so no leads in the terminal of where it could be coming from.
Thank you in advance.
Your problem is likely a result of not including the waitkey() statement at the end of your while loop. It takes time for openCV to load the image, so if the program doesn't pause for long enough for the image to be drawn, the display just doesn't update. Check out this other StackOverflow question for more details.
In addition, you have your ret and frame variables mixed up. ret should be the first one and frame should be the second. Right now, the drawContours() method isn't going to do anything because you're passing it a boolean instead of an image.
Making those changes fixed this for me using Python 3.9 and OpenCV 4.5.

Unable to focus on the number plate of a truck image, and retrieve it in order to put in a different folder

]3
Kindly ignore that the images of input and output trucks are different. In reality, the output should be the focused number plate of the input image (the entire truck).
I have been trying to detect nameplates from a truck image. I followed instructions from a website, but I am unable to focus on the number plate alone and retrieve it. In the end, I am getting green lines at random places on the truck image. The website tells me to convert the original image into grey scale and many more after which it is supposed to detect the number plate, but it is not happening.
I am new to open CV and just following what a website suggested me to. My goal is to retrieve only the number-plate from the truck image and put it into a different folder.
Suggestions on where I can understand these things would be helpful.
import cv2
import numpy as np
img =
cv2.imread("path")
cv2.namedWindow("Original Image",cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("Original Image",img)
# Display image
# RGB to Gray scale conversion
img_gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
cv2.namedWindow("Gray Converted Image",cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("Gray Converted Image",img_gray)
# Display Image
# Noise removal with iterative bilateral filter(removes noise while preserving edges)
noise_removal = cv2.bilateralFilter(img_gray,9,75,75)
cv2.namedWindow("Noise Removed Image",cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("Noise Removed Image",noise_removal)
# Display Image
# Histogram equalisation for better results
equal_histogram = cv2.equalizeHist(noise_removal)
cv2.namedWindow("After Histogram equalisation",cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("After Histogram equalisation",equal_histogram)
# Display Image
# Morphological opening with a rectangular structure element
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
morph_image = cv2.morphologyEx(equal_histogram,cv2.MORPH_OPEN,kernel,iterations=15)
cv2.namedWindow("Morphological opening",cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("Morphological opening",morph_image)
# Display Image
# Image subtraction(Subtracting the Morphed image from the histogram equalised Image)
sub_morp_image = cv2.subtract(equal_histogram,morph_image)
cv2.namedWindow("Subtraction image", cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("Subtraction image", sub_morp_image)
# Display Image
# Thresholding the image
ret,thresh_image = cv2.threshold(sub_morp_image,0,255,cv2.THRESH_OTSU)
cv2.namedWindow("Image after Thresholding",cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("Image after Thresholding",thresh_image)
# Display Image
# Applying Canny Edge detection
canny_image = cv2.Canny(thresh_image,250,255)
cv2.namedWindow("Image after applying Canny",cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("Image after applying Canny",canny_image)
# Display Image
canny_image = cv2.convertScaleAbs(canny_image)
# dilation to strengthen the edges
kernel = np.ones((3,3), np.uint8)
# Creating the kernel for dilation
dilated_image = cv2.dilate(canny_image,kernel,iterations=1)
cv2.namedWindow("Dilation", cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("Dilation", dilated_image)
# Displaying Image
# Finding Contours in the image based on edges
new,contours, hierarchy = cv2.findContours(dilated_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours= sorted(contours, key = cv2.contourArea, reverse = True)[:10]
# Sort the contours based on area ,so that the number plate will be in top 10 contours
screenCnt = None
# loop over our contours
for c in contours:
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.06 * peri, True) # Approximating with 6% error
# if our approximated contour has four points, then
# we can assume that we have found our screen
if len(approx) == 4: # Select the contour with 4 corners
screenCnt = approx
break
final = cv2.drawContours(img, [screenCnt], -1, (0, 255, 0), 3)
# Drawing the selected contour on the original image
cv2.namedWindow("Image with Selected Contour",cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("Image with Selected Contour",final)
# Masking the part other than the number plate
mask = np.zeros(img_gray.shape,np.uint8)
new_image = cv2.drawContours(mask,[screenCnt],0,255,-1,)
new_image = cv2.bitwise_and(img,img,mask=mask)
cv2.namedWindow("Final_image",cv2.WINDOW_NORMAL)
cv2.imshow("Final_image",new_image)
# Histogram equal for enhancing the number plate for further processing
y,cr,cb = cv2.split(cv2.cvtColor(new_image,cv2.COLOR_RGB2YCrCb))
# Converting the image to YCrCb model and splitting the 3 channels
y = cv2.equalizeHist(y)
# Applying histogram equalisation
final_image = cv2.cvtColor(cv2.merge([y,cr,cb]),cv2.COLOR_YCrCb2RGB)
# Merging the 3 channels
cv2.namedWindow("Enhanced Number Plate",cv2.WINDOW_NORMAL)
# Creating a Named window to display image
cv2.imshow("Enhanced Number Plate",final_image)
# Display image
cv2.waitKey() # Wait for a keystroke from the user
l_plate_img = img[screenCnt[0]:screenCnt[1], screenCnt[2]:screenCnt[3]
should return just the part of your image containing the license plate, all further processing can be done on this object.

How to resize output images in python?

Hi i run this blurdetection code in python ( source : https://www.pyimagesearch.com/2015/09/07/blur-detection-with-opencv/ )
# import the necessary packages
from imutils import paths
import argparse
import cv2
def variance_of_laplacian(image):
# compute the Laplacian of the image and then return the focus
# measure, which is simply the variance of the Laplacian
return cv2.Laplacian(image, cv2.CV_64F).var()
# loop over the input images
for imagePath in paths.list_images("images/"):
# load the image, convert it to grayscale, and compute the
# focus measure of the image using the Variance of Laplacian
# method
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
fm = variance_of_laplacian(gray)
text = "Not Blurry"
# if the focus measure is less than the supplied threshold,
# then the image should be considered "blurry"
if fm < 100:
text = "Blurry"
# show the image
cv2.putText(image, "{}: {:.2f}".format(text, fm), (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 3)
cv2.imshow("Image", image)
print("{}: {:.2f}".format(text, fm))
key = cv2.waitKey(0)
with this 2173 x 3161 input file
input image
and this is the output show
the output image
The image is zoom in and dont shown full.
In the source code, they use 450 x 600 px input image :
input in source code
and this is the output :
output in source code
I think the pixels of the image influences of the output. So, how can i get the output like the output in source code to all image?
do i have to resize the input image? How to? but if I do it I'm afraid it will affect the result of his blur
Excerpt from the DOCUMENTATION.
There is a special case where you can already create a window and load image to it later. In that case, you can specify whether window is resizable or not. It is done with the function cv2.namedWindow(). By default, the flag is cv2.WINDOW_AUTOSIZE. But if you specify flag to be cv2.WINDOW_NORMAL, you can resize window. It will be helpful when image is too large in dimension and adding track bar to windows.
I just used the code placed in the question but added line cv2.namedWindow("Image", cv2.WINDOW_NORMAL) as mentioned in the comments.
# import the necessary packages
from imutils import paths
import argparse
import cv2
def variance_of_laplacian(image):
# compute the Laplacian of the image and then return the focus
# measure, which is simply the variance of the Laplacian
return cv2.Laplacian(image, cv2.CV_64F).var()
# loop over the input images
for imagePath in paths.list_images("images/"):
# load the image, convert it to grayscale, and compute the
# focus measure of the image using the Variance of Laplacian
# method
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
fm = variance_of_laplacian(gray)
text = "Not Blurry"
# if the focus measure is less than the supplied threshold,
# then the image should be considered "blurry"
if fm < 100:
text = "Blurry"
# show the image
cv2.putText(image, "{}: {:.2f}".format(text, fm), (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 3)
cv2.namedWindow("Image", cv2.WINDOW_NORMAL) #---- Added THIS line
cv2.imshow("Image", image)
print("{}: {:.2f}".format(text, fm))
key = cv2.waitKey(0)
In case you want to use the exact same resolution as the example you've given, you can just use the cv2.resize() https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#resize method or (in case you want to keep the ratio of the x/y coordinates) use the imutils class provided in https://www.pyimagesearch.com/2015/02/02/just-open-sourced-personal-imutils-package-series-opencv-convenience-functions/
You still have to decide if you want to do the resizing first. It shouldn't matter in which order you greyscale or resize.
Command you can add:
resized_image = cv2.resize(image, (450, 600))

Categories

Resources