How to remove shadow of moving object from image using opencv (python)? - python

I am trying to do background subtraction using MOG2, It was working fine, but when there is deep shadow of a moving object then the shadow is considered as foreground object and I don't want that shadow as foreground object (I'm running MOG2 for 13 images). How can I remove these shadow so that it does not come in foreground?
Here is a sample image...
original img
image after applying MOG2
here is my sample code...
import os
import numpy as np
import cv2
import glob
import imutils
i=0
bg_flag = 0
image_list = []
bgs_list = []
#bgsfinal function
def detection(image_list):
global i
global bg_flag
bgs3_img = None
backsub = cv2.createBackgroundSubtractorMOG2(128, cv2.THRESH_BINARY, 1)
print("start2")
for k in range(len(image_list)):
frame = image_list[k]
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imwrite('./gray/'+str(k)+'.jpg', frame)
#blur = cv2.medianBlur(frame, 21)
blur = frame
bgs_list.append(blur)
for bg in range(len(bgs_list)):
rects = []
#start_time = time.time()
frame_blur = bgs_list[bg]
img = image_list[bg].copy()
s_frame = image_list[bg]
new_frame = s_frame.copy()
fgmask = backsub.apply(frame_blur)
cv2.imwrite("./bgs/"+str(i)+".jpg", fgmask)
fgmask[fgmask==127] = 0
cv2.imwrite("./dilate/"+str(i)+".jpg", fgmask)
thresh = cv2.threshold(fgmask, 128, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.erode(thresh, None, iterations = 1)
thresh = cv2.dilate(thresh, None, iterations=1)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
for c in cnts:
#M = cv2.moments(c)
A = cv2.contourArea(c)
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(new_frame, (x, y), (x + w, y + h), (0,0, 255), 1)
cv2.putText(new_frame, str(A), (x - 10, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
cv2.imwrite("./area/"+str(i)+".jpg", new_frame)
cv2.rectangle(thresh, (x, y), (x + w, y + h), (255,255, 255), 1)
cv2.putText(thresh, str(A), (x - 10, y - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
cv2.imwrite("./area_bgs/"+str(i)+".jpg", thresh)
i+=1
print("Done!")
#this folder contains 13 continuous images
images = glob.glob('./inci4/*.jpg')
for j in range(len(images)):
img = cv2.imread(images[j])
img = cv2.resize(img, (360, 640))
image_list.append(img)
detection(image_list)

Related

OpenCV how to detect in specific position

Can i detect already in square fires in specific positions? I already have a code for detect fire and specific position for view but can i change to minimal position?
Also can i run a "main" (function name is "main") function every 5 minute but different times? Now my code:
import cv2
import numpy as np
import math
import time
import asyncio
from asyncio import sleep
yukseklik = int(input("Yukseklik giriniz "))
hiz = input("Hizi giriniz ")
global kez
kez=0
cap = cv2.VideoCapture(0)
while True:
_, frame = cap.read()
hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Red color
low_red = np.array([0, 80, 20])
high_red = np.array([35, 255, 255])
kernal = np.ones((5, 5), "uint8")
low_red1 = np.array([160, 100, 20])
high_red1 = np.array([190, 255, 255])
red_mask = cv2.inRange(hsv_frame, low_red, high_red)
red = cv2.bitwise_and(frame, frame, mask=red_mask)
contours, hierarchy = cv2.findContours(red_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.rectangle(frame, (213, 160), (426, 320), (255,255,255), 4)
for pic, contour in enumerate(contours):
area = cv2.contourArea(contour)
if(area > 300):
x, y, w, h = cv2.boundingRect(contour)
imframe = cv2.rectangle(frame, (x-20, y+20),(x + w, y + h),(255, 255,255),2)
if(x>213 and x<426 and y<320 and y>160):
if(kez == 0):
def main():
g = 9.80
y = 2*(yukseklik-15)
u = float(y)/9.80
x_ = math.sqrt(u)
x_ = x_*float(hiz)
xi = float(yukseklik)*1.73205080756887729352744463415059
print("x= ",str(xi))
print("x'= ", str(x_))
t = (float(xi)-float(x_))/float(hiz)
print("t= ",t)
global kez
kez = kez+1
asyncio.sleep(5)
kez = 0
main()
cv2.imshow("Frame", frame)
cv2.imshow("Red", red)
key = cv2.waitKey(1)
if key == 27:
break
Output:

Load multiple images with a time interval to overlay an object in a webcam feed

I'm trying to load several images from a folder so that they are processed in an exact same manner. The code below detects a blue object in webcam feed and overlays it with the template image img where the webcam frame is im0
hsv = cv2.cvtColor(im0, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, (0, 120, 120), (180, 255, 255))#<- blue # RED: (0, 120, 120), (10, 255, 255))
thresh = cv2.dilate(mask, None, iterations=2)
contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0]
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
height = 480
width = 640
if y + h < height and x + w < width:
logo = cv2.resize(img, (w, h))
img2gray = cv2.cvtColor(logo, cv2.COLOR_BGR2GRAY)
_, logo_mask = cv2.threshold(img2gray, 1, 255, cv2.THRESH_BINARY)
roi = im0[y:y+h, x:x+w]
roi[np.where(logo_mask)] = 0
roi += logo
cv2.imshow(str(p), im0)#im0 2
cv2.waitKey(1) # 1 millisecond
I am wondering how should I create a timer here so that the exact same processing happens to the img2, img3 and so on?

Object Detection Using Raspberry Pi and Android IP Camera with Python and OpenCV

Here is my code that I have used for object detection using raspberry pi and Android Ip Camera. Here I'm not getting any output and the code does not provide any errors. Can someone figure out what is the error?
import urllib.request
import cv2
import numpy as np
import datetime
import math
#global variables
width = 0
height = 0
EntranceCounter = 0
ExitCounter = 0
MinCountourArea = 3000 #Adjust ths value according to your usage
BinarizationThreshold = 70 #Adjust ths value according to your usage
OffsetRefLines = 150 #Adjust ths value according to your usage
#Check if an object in entering in monitored zone
def CheckEntranceLineCrossing(y, CoorYEntranceLine, CoorYExitLine):
AbsDistance = abs(y - CoorYEntranceLine)
if ((AbsDistance <= 2) and (y < CoorYExitLine)):
return 1
else:
return 0
#Check if an object in exitting from monitored zone
def CheckExitLineCrossing(y, CoorYEntranceLine, CoorYExitLine):
AbsDistance = abs(y - CoorYExitLine)
if ((AbsDistance <= 2) and (y > CoorYEntranceLine)):
return 1
else:
return 0
This is the code i have used to obtain the video stream from my IP camera
ReferenceFrame = None
while True:
camera=cv2.VideoCapture("http://192.168.1.6:8080/shot.jpg")
camera.set(3,640)
camera.set(4,480)
(ret,Frame)=camera.read()
height = np.size(Frame,0)
width = np.size(Frame,1)
#if cannot grab a frame, this program ends here.
if not ret:
break
This is the code part i have used to display the lines and frame for object detection and object counting
#gray-scale convertion and Gaussian blur filter applying
GrayFrame = cv2.cvtColor(Frame, cv2.COLOR_BGR2GRAY)
GrayFrame = cv2.GaussianBlur(GrayFrame, (21, 21), 0)
if ReferenceFrame is None:
ReferenceFrame = GrayFrame
continue
#Background subtraction and image binarization
FrameDelta = cv2.absdiff(ReferenceFrame, GrayFrame)
FrameThresh = cv2.threshold(FrameDelta, BinarizationThreshold, 255, cv2.THRESH_BINARY)[1]
#Dilate image and find all the contours
FrameThresh = cv2.dilate(FrameThresh, None, iterations=2)
_, cnts, _ = cv2.findContours(FrameThresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
QttyOfContours = 0
#plot reference lines (entrance and exit lines)
CoorYEntranceLine = (height / 2)-OffsetRefLines
CoorYExitLine = (height / 2)+OffsetRefLines
cv2.line(Frame, (0,CoorYEntranceLine), (width,CoorYEntranceLine), (255, 0, 0), 2)
cv2.line(Frame, (0,CoorYExitLine), (width,CoorYExitLine), (0, 0, 255), 2)
#check all found countours
for c in cnts:
#if a contour has small area, it'll be ignored
if cv2.contourArea(c) < MinCountourArea:
continue
QttyOfContours = QttyOfContours+1
#draw an rectangle "around" the object
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(Frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
#find object's centroid
CoordXCentroid = (x+x+w)/2
CoordYCentroid = (y+y+h)/2
ObjectCentroid = (CoordXCentroid,CoordYCentroid)
cv2.circle(Frame, ObjectCentroid, 1, (0, 0, 0), 5)
if (CheckEntranceLineCrossing(CoordYCentroid,CoorYEntranceLine,CoorYExitLine)):
EntranceCounter += 1
if (CheckExitLineCrossing(CoordYCentroid,CoorYEntranceLine,CoorYExitLine)):
ExitCounter += 1
print ("Total countours found: "+str(QttyOfContours))
#Write entrance and exit counter values on frame and shows it
cv2.putText(Frame, "Entrances: {}".format(str(EntranceCounter)), (10, 50),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (250, 0, 1), 2)
cv2.putText(Frame, "Exits: {}".format(str(ExitCounter)), (10, 70),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow('Salida',Frame)
cv2.waitKey(1);
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
The correct code
import numpy as np
import math
def nothing(x):
pass
width=0
height=0
EntranceCounter = 0
OffsetRefLines = 150
ExitCounter = 0
BinarizationThreshold = 70
MinCountourArea = 3000
cap = cv2.VideoCapture(0);
path="http://192.168.1.6:8080/video"
cap.open(path)
ReferenceFrame = None
#Check if an object in entering in monitored zone
def CheckEntranceLineCrossing(y, CoorYEntranceLine, CoorYExitLine):
AbsDistance = abs(y - CoorYEntranceLine)
if ((AbsDistance <= 2) and (y < CoorYExitLine)):
return 1
else:
return 0
#Check if an object in exitting from monitored zone
def CheckExitLineCrossing(y, CoorYEntranceLine, CoorYExitLine):
AbsDistance = abs(y - CoorYExitLine)
if ((AbsDistance <= 2) and (y > CoorYEntranceLine)):
return 1
else:
return 0
#cv2.namedWindow("Tracking")
cv2.createTrackbar("LH", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LS", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LV", "Tracking", 0, 255, nothing)
cv2.createTrackbar("UH", "Tracking", 255, 255, nothing)
cv2.createTrackbar("US", "Tracking", 255, 255, nothing)
cv2.createTrackbar("UV", "Tracking", 255, 255, nothing)
while True:
#frame = cv2.imread('smarties.png')
if cap.isOpened():
rval, frame = cap.read()
while rval:
rval,frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
hsv = cv2.GaussianBlur(hsv, (21, 21), 0)
if ReferenceFrame is None:
ReferenceFrame = hsv
continue
#Background subtraction and image binarization
FrameDelta = cv2.absdiff(ReferenceFrame, hsv)
FrameThresh = cv2.threshold(FrameDelta, 25, 255, cv2.THRESH_BINARY)[1]
#Dilate image and find all the contours
FrameThresh = cv2.dilate(FrameThresh, None, iterations=2)
cnts, _ = cv2.findContours(FrameThresh, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
QttyOfContours = 0
#plot reference lines (entrance and exit lines)
cv2.line(frame, (0,170), (2000,170), (255, 0, 0), 5)
cv2.line(frame, (0,470), (2000,470), (0, 0, 255), 5)
#check all found countours
for c in cnts:
#if a contour has small area, it'll be ignored
if cv2.contourArea(c) < MinCountourArea:
continue
QttyOfContours = QttyOfContours+1
#draw an rectangle "around" the object
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
#find object's centroid
CoordXCentroid = int(x+x+w)/2
CoordYCentroid = int(y+y+h)/2
ObjectCentroid = (x,y)
cv2.circle(frame, ObjectCentroid, 2, (0, 255, 0), 5)
if (CheckEntranceLineCrossing(CoordYCentroid,170,470)):
EntranceCounter += 1
if (CheckExitLineCrossing(CoordYCentroid,170,470)):
ExitCounter += 1
print ("Total countours found: "+str(QttyOfContours))
#Write entrance and exit counter values on frame and shows it
cv2.putText(frame, "Entrances: {}".format(str(EntranceCounter)), (10, 50),
cv2.FONT_HERSHEY_SIMPLEX, 2, (250, 0, 1), 2)
cv2.putText(frame, "Exits: {}".format(str(ExitCounter)), (10, 110),
cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 2)
imS = cv2.resize(frame, (400, 400)) # Resize image
#imSS = cv2.resize(mask, (200, 200))
#imSSS = cv2.resize(frame, (200, 200))
cv2.imshow("frame", imS)
#cv2.imshow("mask", imSS)
#cv2.imshow("res", imSSS)
key = cv2.waitKey(1)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()

OpenCV - Motion capture with multiple ip cameras

I have three IP cameras around my house and I want to capture an image when a motion is detected. I want to run the motion capture algorithm in the same time for all 3 cameras.
I manage to do the job for one camera - Open the stream + motion detection algorithm + store image in case of detection :
import cv2
cap3 = cv2.VideoCapture('http://X.X.X.X:XXXX/stream.mjpg')
ret3, frame31 = cap3.read()
ret3, frame32 = cap3.read()
while (True):
diff3 = cv2.absdiff(frame31, frame32)
gray3 = cv2.cvtColor(diff3, cv2.COLOR_BGR2GRAY)
blur3 = cv2.GaussianBlur(gray3, (5, 5), 0)
_, tresh3 = cv2.threshold(blur3, 30, 255, cv2.THRESH_BINARY)
dilated3 = cv2.dilate(tresh3, None, iterations=3)
contours3, _ = cv2.findContours(dilated3, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours3:
(x, y, w, h) = cv2.boundingRect(contour)
if cv2.contourArea(contour) < 800:
continue
cv2.rectangle(frame31, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame31, "Status: {}".format('Movement'), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
t = time.localtime()
filename = "RASP" + str(t[0]) + str(t[1]) + str(t[2]) + "_" + str(t[3]) + str(t[4]) + str(t[5]) + ".jpg"
cv2.imwrite(filename, frame31)
frame31 = frame32
ret3, frame32 = cap3.read()
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap3.release()
cv2.destroyAllWindows()
The problem I have is when I try to do the same job in parallel for the three cameras.
What I do is duplicating the same process in the while loop for the three cameras and when I do so, it starts running for a few seconds and then I get this error :
Traceback (most recent call last):
File "C:/Users/Guillaume/PycharmProjects/IPCAM/IPCAM2.py", line 54, in <module>
gray2 = cv2.cvtColor(diff2, cv2.COLOR_BGR2GRAY)
cv2.error: OpenCV(4.2.0) C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'
The code I run in below :
import cv2
import numpy as np
from datetime import datetime
import time
cap2 = cv2.VideoCapture('rtsp://') # IPCAM2
cap = cv2.VideoCapture('rtsp://') # IPCAM1
cap3 = cv2.VideoCapture('http://') # RASP
def rescale_frame(frame, percent=75):
width = int(frame.shape[1] * percent / 100)
height = int(frame.shape[0] * percent / 100)
dim = (width, height)
return cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
while (True):
ret1, frame11 = cap.read()
ret1, frame12 = cap.read()
ret2, frame21 = cap2.read()
ret2, frame22 = cap2.read()
ret3, frame31 = cap3.read()
ret3, frame32 = cap3.read()
diff1 = cv2.absdiff(frame11, frame12)
gray1 = cv2.cvtColor(diff1, cv2.COLOR_BGR2GRAY)
blur1 = cv2.GaussianBlur(gray1, (5, 5), 0)
_, tresh1 = cv2.threshold(blur1, 40, 255, cv2.THRESH_BINARY)
dilated1 = cv2.dilate(tresh1, None, iterations=3)
contours1, _ = cv2.findContours(dilated1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours1:
(x, y, w, h) = cv2.boundingRect(contour)
if cv2.contourArea(contour) < 1000:
continue
cv2.rectangle(frame11, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame11, "Status: {}".format('Movement'), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
t = time.localtime()
filename = str(t[0]) + str(t[1]) + str(t[2]) + "_" + str(t[3]) + str(t[4]) + str(t[5]) + ".jpg"
cv2.imwrite(filename, frame11)
# cv2.line(frame, (0, 300), (200, 200), (0, 255, 0), 5)
resizedframe11 = rescale_frame(frame11, percent=75)
cv2.imshow('frame', resizedframe11)
frame11 = frame12
ret1, frame12 = cap.read()
diff2 = cv2.absdiff(frame21, frame22)
gray2 = cv2.cvtColor(diff2, cv2.COLOR_BGR2GRAY)
blur2 = cv2.GaussianBlur(gray2, (5, 5), 0)
_, tresh2 = cv2.threshold(blur2, 40, 255, cv2.THRESH_BINARY)
dilated2 = cv2.dilate(tresh2, None, iterations=3)
contours2, _ = cv2.findContours(dilated2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours2:
(x, y, w, h) = cv2.boundingRect(contour)
if cv2.contourArea(contour) < 1000:
continue
cv2.rectangle(frame21, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame21, "Status: {}".format('Movement'), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
t = time.localtime()
filename = str(t[0]) + str(t[1]) + str(t[2]) + "_" + str(t[3]) + str(t[4]) + str(t[5]) + ".jpg"
cv2.imwrite(filename, frame21)
resizedframe21 = rescale_frame(frame21, percent=75)
cv2.imshow('frame2', resizedframe21)
frame21 = frame22
ret2, frame22 = cap2.read()
diff3 = cv2.absdiff(frame31, frame32)
gray3 = cv2.cvtColor(diff3, cv2.COLOR_BGR2GRAY)
blur3 = cv2.GaussianBlur(gray3, (5, 5), 0)
_, tresh3 = cv2.threshold(blur3, 40, 255, cv2.THRESH_BINARY)
dilated3 = cv2.dilate(tresh3, None, iterations=3)
contours3, _ = cv2.findContours(dilated3, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours3:
(x, y, w, h) = cv2.boundingRect(contour)
if cv2.contourArea(contour) < 800:
continue
cv2.rectangle(frame31, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame31, "Status: {}".format('Movement'), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
t = time.localtime()
filename = "RASP" + str(t[0]) + str(t[1]) + str(t[2]) + "_" + str(t[3]) + str(t[4]) + str(t[5]) + ".jpg"
cv2.imwrite(filename, frame31)
resizedframe31 = rescale_frame(frame31, percent=75)
cv2.imshow('frame3', resizedframe31)
frame31 = frame32
ret3, frame32 = cap3.read()
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Thanks Kartik and thekangaroo for your answers.
I managed to run my three cameras at the same time using threads. I am just opening them and showing a resized stream.
There is another issue as one cameras, and then a second, stops after a random time between 5 to 20 seconds. The stream stops and then the windows closes without any messages.
It seems to me that it is due to lagging getting the image from the cameras... any ideas to avoid that with openCV ?
Thanks again for your helpful answers.
Below is the code I use :
import cv2
import threading
import time
class camThread(threading.Thread):
def __init__(self, previewName, camID):
threading.Thread.__init__(self)
self.previewName = previewName
self.camID = camID
def run(self):
print("Starting " + self.previewName)
camPreview(self.previewName, self.camID)
def rescale_frame(frame, percent=75):
width = int(frame.shape[1] * percent / 100)
height = int(frame.shape[0] * percent / 100)
dim = (width, height)
return cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
def camPreview(previewName, camID):
cv2.namedWindow(previewName)
cam = cv2.VideoCapture(camID)
if cam.isOpened(): # try to get the first frame
rval, frame = cam.read()
else:
time.sleep(10)
rval, frame = cam.read()
percent = 50
width = int(frame.shape[1] * percent / 100)
height = int(frame.shape[0] * percent / 100)
dim = (width, height)
while rval:
# cv2.imshow(previewName, frame)
cv2.imshow(previewName, cv2.resize(frame, dim, interpolation=cv2.INTER_AREA))
time.sleep(0.5)
rval, frame = cam.read()
key = cv2.waitKey(20)
print(previewName + str(cam.isOpened()))
# Create two threads as follows
thread1 = camThread("CLIO", 'rtsp://xxxx')
thread2 = camThread("JARDIN", 'rtsp://xxxx')
thread3 = camThread("RASPCAM", 'http://xxxx')
thread1.start()
thread2.start()
thread3.start()

How do I use opencv to identify and label shapes

I am trying to use opencv to create a rectangle around a cone. Where I am currently at is I have outlined the code which has resulted in a triangle shape. How can I use opencv to create a rectangle around the triangle.
My code so far:
import cv2
import numpy as np
img = cv2.imread('image.jpg')
ret, mask = cv2.threshold(img[:, :,2], 235, 255, cv2.THRESH_BINARY)
mask3 = np.zeros_like(img)
mask3[:, :, 0] = mask
mask3[:, :, 1] = mask
mask3[:, :, 2] = mask
orange = cv2.bitwise_and(img, mask3)
cv2.imwrite("output.jpg", orange)
im = cv2.imread('output.jpg')
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(im, contours, -1, (0,255,0), 3)
cv2.imshow('img',im)
cv2.waitKey(0)
cv2.destroyAllWindows
Jpeg File:
One approach is using multi-scale template matching
You crop the object you want to find:
Apply Canny edge-detection to find the edges
edged = cv2.Canny(resized, 50, 200)
Find the matched template using matchTemplate
result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF)
Result:
Code:
import numpy as np
import imutils
import glob
import cv2
template = cv2.imread("template.jpg")
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
template = cv2.Canny(template, 50, 200)
(h, w) = template.shape[:2]
for imagePath in glob.glob("img2" + "/pXobJ.jpg"):
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
found = None
for scale in np.linspace(0.2, 1.0, 20)[::-1]:
resized = imutils.resize(gray, width=int(gray.shape[1] * scale))
r = gray.shape[1] / float(resized.shape[1])
if resized.shape[0] < h or resized.shape[1] < w:
break
edged = cv2.Canny(resized, 50, 200)
result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF)
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
if found is None or maxVal > found[0]:
found = (maxVal, maxLoc, r)
(_, maxLoc, r) = found
(startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))
(endX, endY) = (int((maxLoc[0] + w) * r), int((maxLoc[1] + h) * r))
cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2)
cv2.imwrite("img2/out.jpg", image)
print("Table coordinates: ({}, {}, {}, {})".format(startX, startY, endX, endY))
You can also use deep learning object detection with trained networks.

Categories