I have captured some data in a 16x8 heatmap matrix called pixels.
I would like to do some blob recognition on this matrix data and display the result on the screen.
I was able to do this in a very convoluted way by displaying the data as an image and saving it to a RAM disk then performing blob recognition:
Display data as an image
get the current figure drawn
save image to RAM disk
detect blobs
display image
It' slow. Is there an easier/shorter way to detect blobs in a matrix? Or at least skipping the ramdisk save? Thank you!
The code:
# Display data as an image. maybe not necessary?
rez = plt.imshow(np.reshape(np.repeat(0,128),(16,8)),cmap=plt.cm.hot,interpolation='hanning')
plt.draw()
plt.pause(0.0005)
# read data
pixels = s.readData()
# update data
rez.set_data(np.reshape(pixels,(16,8)))
# get the current figure drawn
fig1 = plt.gcf()
# save to RAM disk
fig1.savefig('/home/pi/ramdisk/img.png', dpi=300)
# Read image
im0 = cv2.imread("/home/pi/ramdisk/img.png", cv2.IMREAD_COLOR)
im1 = cv2.imread("/home/pi/ramdisk/img.png", cv2.IMREAD_GRAYSCALE)
im = cv2.threshold(im1, 158, 255, cv2.THRESH_BINARY_INV)[1]
params = cv2.SimpleBlobDetector_Params()
params.minArea =50
detector = cv2.SimpleBlobDetector_create(params)
# Detect blobs.
keypoints = detector.detect(im)
# Draw detected blobs
im_with_keypoints = cv2.drawKeypoints(im0, keypoints, np.array([]), (0,255,0), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
#display image with blobs
....
Related
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)
I have a problem with canny edge detection in python.
my starting picture is a normal picture of a bill like I have added in the post.
I detect the edges with canny without any problems but I want to know where the longest detected edges are in the picture.
Here is the input image
and here is the output image.
Now I want to know the longest edge in the output image to cut of the unnecessary parts of the picture, but I do not know how...
My Code:
# Read reference image
#refFilename = RefRefFileCalculation(row)
refFilename = "C:\\Maturaprojekt\\Test 1\\30Zeilen.JPG"
print("Reading reference image : ", refFilename)
imReference = cv2.imread(refFilename, cv2.IMREAD_COLOR)
# Read image to be aligned
imFilename = save_path
print("Reading image to align : ", imFilename);
im = cv2.imread(imFilename, cv2.IMREAD_COLOR)
print("Aligning images ...")
# Registered image will be resotred in imReg.
# The estimated homography will be stored in h.
imReg, h = alignImages(im, imReference)
# Write aligned image to disk.
outFilename = "C:\\Maturaprojekt\\Test 1\\gedreht\\" + sample_names[i]
print("Saving aligned image : ", outFilename);
cv2.imwrite(outFilename, imReg)
# Load the image file
image = cv2.imread(save_path)
# Check if image was loaded improperly and exit if so
if image is None:
sys.exit('Failed to load image')
# Detect edges in the image. The parameters control the thresholds
edges = cv2.Canny(image, 100, 700, apertureSize=5)
# Display the output in a window
cv2.imwrite("C:\\Maturaprojekt\\Edge Detection Test 1\\cropped\\" + sample_names[i], edges)
i = i+1
I want to measure area of land in an aerial view image, so I was adviced to first use blob detection to Isolate region and threshold the image. Here is what I have done, but I am not sure if this is correct.
img = cv2.imread('landarea.jpg', cv2.IMREAD_COLOR)
# Set up the detector with default parameters.
detector = cv2.SimpleBlobDetector_create()
# Detecting blobs.
keypoints = detector.detect(img)
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures the size of the circle corresponds to the size
im_with_keypoints = cv2.drawKeypoints(img, keypoints, np.array([]), (0, 0,
255),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Show keypoints
print(im_with_keypoints.size)
# plt.show()
cv2.imshow("Blob",im_with_keypoints )
cv2.waitKey(0)
cv2.destroyAllWindows()
# Convert to gray
gray = cv2.cvtColor(im_with_keypoints, cv2.COLOR_BGR2GRAY)
#Threshold the image
ret3,th3 = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
titles = ["Otsu's Thresholding"]
images = [th3]
plt.figure(figsize=(15, 10))
for i in range(1):
plt.subplot(1,1,i+1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
Image Link
In summary this is what I am trying to achieve
Task : Land Area Measurement:
I am current working on getting the Area, Width and Height Measurement of a Land from aerial Mapping Images. Steps taken to achieve this are listed below:
I was advice that it's better to write a Python code from scratch to do my Image processing.
Also from SO, I was advice to use a blob detector to isolates regions, threshold my image and count the number of white pixels. Then I can calibrate the dimensions of the image with ground truth dimensions.
I have been able to detect blobs, threshold the image and I have also been able to get the count of white pixels. My major challenge is on the last two steps and how to get the measurement from this steps.
Also a friend said that normally the shape of any photo could be square, rectangle, etc. So the area might not vary if I measure area with photos.
I do not think blob detection is going to work well. You would need to threshold the image in some way to separate the land area from everything else. From what part of the image do you want to get the area?
]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.
I am trying to remove small images from graphs using Python. As an example, I attach a graph with some '+' and '-' annotating it. I don't want them there, but don't want to manually remove them as there are quite a few to go through. Any easy way to detect and remove them?
I'll give you a solution using blob analysis since I had it almost ready at hand, but would ask you to do the reading and explanation yourself, since you have not spent too much time on your own code. Maybe it helps anyway.
Resulting image:
import numpy as np
import cv2
imgray = cv2.imread('image.png')
#### Blob analysis
# SimpleBlobDetector will find black blobs on white surface
ret,imthresh = cv2.threshold(imgray,160, 255,type=cv2.THRESH_BINARY)
# Remove small breaks in lines
kernel = np.ones((3,3),np.uint8)
imthresh=cv2.erode(imthresh,kernel, iterations=1)
# Setup SimpleBlobDetector parameters.
params = cv2.SimpleBlobDetector_Params()
# Filter by Area.
params.filterByArea = True
params.minArea = 0
params.maxArea =350
# Don't filter by Circularity
params.filterByCircularity = False
# Don't filter by Convexity
params.filterByConvexity = False
# Don't filter by Inertia
params.filterByInertia = False
# Create a detector with the parameters
detector = cv2.SimpleBlobDetector_create(params)
# Detect blobs.
keypoints = detector.detect(imthresh)
# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures
# the size of the circle corresponds to the size of blob
im_with_keypoints = cv2.drawKeypoints(imthresh, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# Show blobs
cv2.imshow("Keypoints", im_with_keypoints)
cv2.imshow('threshold',imthresh)
cv2.waitKey(0)
cv2.destroyAllWindows()