How can I get bounding box around the specific quadrants(locations) the difference is in, instead of the exact difference of contents in image?

asked 2019-01-18 17:11:22 -0600

Firelife gravatar image

updated 2020-10-04 11:39:58 -0600

I have managed to bring in a image, turn it to grayscale, create a mask over specific points of interests. I can compare the first image to multiple of images to get a differences and created a bounding box around the test image locations that are different.

The bounding boxes go around the contents that are different. I want bound the box around the quadrants(specific locations) produced from the difference.image description

The locations are based off lines 36-69. image description

When I to compare Empty lot to Test image, The following bounding boxes occur. This is put on the original picture for clarity.

image description

I want create if then statements for each spot, based on the quadrants to produce a 1 or 0. If there is a red bounding box or a green bounding box.

I put screen shots of the other 2 test images. To show I am getting pretty good comparisons to what is in the spaces.

image description image description

The following is the code:

import cv2
import numpy as np
from colors import COLOR_WHITE, COLOR_RED    #imports colors from colors.py
from skimage.measure import compare_ssim
import imutils

#Get image(Empty Lot) and image(Test Spots in Lot)
img = cv2.imread('IMG_0940.jpg')
img2 = cv2.imread('IMG_0941.jpg')

#Resize both images to same size
r = 480 / img.shape[1]
dim = (480, int(img.shape[0]*r))
small = cv2.resize(img,dim,interpolation = cv2.INTER_AREA)

r1 = 480 / img2.shape[1]
dim = (480, int(img2.shape[0]*r1))
small2 = cv2.resize(img2,dim,interpolation = cv2.INTER_AREA)

#Display the both resized images
#cv2.imshow("Empty Lot",small)
#cv2.imshow("Test Spots in Lot",small2)
#cv2.waitKey(0)

#Convert to gray scale on img, img2
smallgray = cv2.cvtColor(small,cv2.COLOR_BGR2GRAY)
small2gray = cv2.cvtColor(small2,cv2.COLOR_BGR2GRAY)

#Apply GaussianBlur to both img and img2
blur = cv2.GaussianBlur(smallgray,(9,9),0)
blur2 = cv2.GaussianBlur(small2gray,(9,9),0)

#Create the basic black image
mask = np.zeros(blur.shape, dtype="uint8")

#Draw a white, filled rectangle on the mask image, "S" Startpoint, "E" Endpoint
#Specific locations of spots to compare
S = [(14,137),(14,174),(14,214),(14,252),(14,290),(14,328),(14,366),(14,402),
       (161,65),(199,102),(234,139),(270,179),(306,217),(344,254),(381,293),
       (235,65),(273,102),(308,139),(344,179),(380,217),(418,254)];
E = [(80,166),(80,204),(80,244),(80,282),(80,320),(80,358),(80,396),(80,432),
     (227,94),(265,131),(300,168),(336,208),(372,246),(410,283),(447,322),
     (301,94),(339,131),(374,168),(410,208),(446,246),(478,283)];

#Layout of 3 rows of the parking lot   

A0 = cv2.rectangle(mask, (S[0]),(E[0]), (COLOR_WHITE), -1)
A1 = cv2.rectangle(mask, (S[1]),(E[1]), (COLOR_WHITE), -1)
A2 = cv2.rectangle(mask, (S[2]),(E[2]), (COLOR_WHITE), -1)  
A3 = cv2.rectangle(mask, (S[3]),(E[3]), (COLOR_WHITE), -1) 
A4 = cv2.rectangle(mask, (S[4]),(E[4]), (COLOR_WHITE), -1) 
A5 = cv2.rectangle(mask, (S[5]),(E[5]), (COLOR_WHITE), -1) 
A6 = cv2.rectangle(mask, (S ...
(more)
edit retag flag offensive close merge delete

Comments

and the problem is, now ?

berak gravatar imageberak ( 2019-01-19 01:57:09 -0600 )edit
1

I am able to compare the two images and get bounding boxes.

The problem is the bounding boxes are around the exact differences. I want the bounding box around the quadrant the difference is in.

This is in efforts to create boolens. If there is not a bounding box at specific quadrant the spot is empty.

Firelife gravatar imageFirelife ( 2019-01-19 08:16:32 -0600 )edit
1

By quadrant you mean, literal quadrant? The quarter of the image, like top left, bottom right, ect?

Or something else?

Tetragramm gravatar imageTetragramm ( 2019-01-19 14:12:03 -0600 )edit
1

I was hoping for the actual locations I created on the mask. The specific locations of A0-A7, B0-B6, and C0-C5.

Or some way to mark the locations that there is something there or not. This is to let me send an array of 1 or 0 to firebase database set.

Firelife gravatar imageFirelife ( 2019-01-19 17:16:50 -0600 )edit

Have you figured out how to tell the difference between occupied and not? For just one box, can you tell the difference?

Tetragramm gravatar imageTetragramm ( 2019-01-20 17:35:29 -0600 )edit

No I have not been able to. I was able to get the differences from the two images. I was hoping to compare each location actually of inside contents. Then bound or fill in with color.

Like A0 in empty lot image to A0 in test image. Then bound A0 If bounded with red produce a 1. If not bounded produce a zero.

Firelife gravatar imageFirelife ( 2019-01-21 04:40:24 -0600 )edit

Ok, so try this: use the absdiff function to subtract your "empty" image from the current image (the one you're trying to tell if there's a car).

Then, use the rectangle for A0 to extract a region of interest, and calculate the sum of every pixel inside it. If the sum is greater than some threshold (and you will need to do some tests to find a good threshold), then you mark it as occupied.

Tetragramm gravatar imageTetragramm ( 2019-01-21 22:28:40 -0600 )edit

Ok, I was able to use the function absdiff between the two images. I cropped the A0 location in both empty lot and the image with the car. I then compared the two and created an "If" statement. It works.

How do I crop all the locations of the of a np array.The following is how I have the array setup.

rect = np.array([14,137,80,166],[],[],[]) Ect. ([x1,y1,x2,y2]). Total of 21 elements.

The crop function takes in (y1:y2,x1:x2)

crop ROI locations crop_empty = smallgray[174:204,14:80].copy()

cv2.imshow("crop_empty",crop_empty)

Firelife gravatar imageFirelife ( 2019-01-29 08:38:01 -0600 )edit

Are you saying you've got it all working, or is there another question there?

Tetragramm gravatar imageTetragramm ( 2019-01-29 22:55:55 -0600 )edit

I was able to crop one element. Not each element in the rect np.array. How do I crop all of the spots from both images, into separate arrays. Then compare the two arrays, cropped empty to cropped cars. I was trying to do a for loop but errors out, I was also told it will be very slow slow.

Thanks

Firelife gravatar imageFirelife ( 2019-01-30 06:51:07 -0600 )edit

It sounds like you need to practice your basic python. It looks like you've got everything in lists, and if you can do something with the first element of the list, doing it with the rest should be easy.

Tetragramm gravatar imageTetragramm ( 2019-01-30 17:50:10 -0600 )edit