RCNN Nesne tespiti (Object detection)

Serhan ayberk Kılıç
4 min readNov 6, 2021

--

R-cnn ile araç tespiti modelinin geliştirebilmke için kaggle’da bulunan https://www.kaggle.com/sshikamaru/car-object-detection datasetini kullandım.

Gerekli kütüphaneleri ekliyoruz.

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import cv2
import os
import random
import warnings
warnings.filterwarnings("ignore")

Datasetin içinde Train ve Test olmak üzere 2 adet klasör var. Klasörlerde bulunan görsel sayıları:

!unzip "/r-cnn_car/archive.zip" -d "/content/"print('Image(Train):',len(os.listdir('/content/data/training_images')))
print('Image(Test):',len(os.listdir('/content/data/testing_images')))

Image(Train): 1001

Image(Test): 175

Label(Etiket) için hazırlanmış csv dosyamızı okuyup içeriğine bakıyoruz.

Data=pd.read_csv('/content/data/train_solution_bounding_boxes (1).csv')
Data.head()
print(‘Train data localization:’,len(Data))

Train data localization: 559

for i in Data.values:
photo=plt.imread(f'/content/data/training_images/{i[0]}')
plt.imshow(photo)
print('Photo shape:',photo.shape)
print('Name,xmin,ymin,xmax,ymax:',i)
pt1=(int(i[1]),int(i[2]))
pt2=(int(i[3]),int(i[4]))
color=(255, 0, 0)
thickness = 2
cv2.rectangle(photo,pt1,pt2, color, thickness)
plt.figure()
plt.imshow(photo)
break

Selective Search Nedir?

Selective Search, nesne tespitinde kullanılan bir bölge önerisi algoritmasıdır. Çok yüksek bir geri çağırma ile hızlı olacak şekilde tasarlanmıştır. Renk, doku, boyut ve şekil uyumluluğuna dayalı olarak benzer bölgelerin hiyerarşik gruplandırmasını hesaplamaya dayanır.

Araç tespitinde Selective Search algoritmasının kullanılması:

cv2.setUseOptimized(True) 
cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()
im = cv2.imread('/content/data/training_images/vid_4_1000.jpg')
im=cv2.resize(im,(224,224))
plt.figure()
plt.imshow(im)
ss.setBaseImage(im) # Görüntünün yüklendiği kısım
ss.switchToSelectiveSearchFast() # Selective Search süresini hızlandırmak için
rects = ss.process()
print('Shape:',im.shape)
print('possible bounty boxes:',len(rects))
for rect in rects:
x, y, w, h = rect
imOut=cv2.rectangle(im, (x, y), (x+w, y+h), (0, 255, 0), 1, cv2.LINE_AA)
plt.figure()
plt.imshow(imOut);

IOU Nedir?

Coursera’ da bulunan CNN derslerinde anlatıldığı üzere;

tahmin edilen bounty box ile kordinatları doğru olan bounty box’ın kesişiminin 2 alanın birlikteliğine oranı olarak ifade edilmektedir. Aşağıdaki görselde net olarak gözükmektedir.

IOU hesabın kod olarak yapılması:

cv2.setUseOptimized(True)
ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()
def get_iou(bb1, bb2):
assert bb1['x1'] < bb1['x2'] #bb1
assert bb1['y1'] < bb1['y2']
assert bb2['x1'] < bb2['x2'] #bb2
assert bb2['y1'] < bb2['y2']
x_left = max(bb1['x1'], bb2['x1'])
y_top = max(bb1['y1'], bb2['y1'])
x_right = min(bb1['x2'], bb2['x2'])
y_bottom = min(bb1['y2'], bb2['y2'])
if x_right < x_left or y_bottom < y_top:
return 0.0
intersection_area = (x_right - x_left) * (y_bottom - y_top)
bb1_area = (bb1['x2'] - bb1['x1']) * (bb1['y2'] - bb1['y1'])
bb2_area = (bb2['x2'] - bb2['x1']) * (bb2['y2'] - bb2['y1'])
iou = intersection_area / float(bb1_area + bb2_area - intersection_area)
assert iou >= 0.0
assert iou <= 1.0
return iou

Araç datamızda bulunan görsellere selective search algoritmasını uygulayarak etiktellerdeki doğru bounty boxlarla kıyaslama yaptırıp IoU değeri 0.5 den yüksek olanlara 1 etiketi 0.5 den düşük olanlara 0 etiketi vererek. Modelleştirme için datamızı hazırlıyoruz. Önemli bir nokta olarak selective search algoritması muhtemel olarak 2000 adet bounty box bulabilmektedir. Modelde bias(yanlılık)oluşmaması için etiketi 1 ve 0 olan görsel parçalardan eşit sayıda almak önemlidir. Aşağıdaki kod bloğu bu işlemleri yapmaktadır.

image_liste=[]
k=0
l=0
z=0 #Loading
for a in pd.read_csv('/content/data/train_solution_bounding_boxes (1).csv').values:
Name,xmin,ymin,xmax,ymax=a
bb1={ #gerçek bounty boxxes'x1':int(xmin),y1':int(ymin),'x2':int(xmax),'y2':int(ymax)}
try:
img=cv2.imread('/content/data/training_images/'+Name)
ss.setBaseImage(img)
ss.switchToSelectiveSearchFast()
rects = ss.process()
for i in rects:
x, y, w, h = i # Selective bounty boxxes
bb2={'x1':x,'y1':y,'x2':x+w,'y2':y+h}
img1=img[bb2['y1']:bb2['y2'],bb2['x1']:bb2['x2']] # Crop img
img1_shape=cv2.resize(img1,(224,224))
if k<l:
if 0.5<get_iou(bb1,bb2):
image_liste.append([img1_shape,1])
k+=1
else:
if 0.5<get_iou(bb1,bb2):
image_liste.append([img1_shape,1])
k+=1
else:
image_liste.append([img1_shape,0])
l+=1
except Exception as e:
print('hata var',e)
z+=1
print(Name,z,len(rects))

vid_4_1000.jpg 1 1101

vid_4_10000.jpg 2 1456

vid_4_10040.jpg 3 1403

vid_4_10020.jpg 4 1489

data=[]
data_label=[]
for features,label in image_liste:
data.append(features)
data_label.append(label)
print('işlem başarılı')
print('Fotoğraf sayısı:',len(data),'|Label sayısı:',len(data_label))

işlem başarılı

Fotoğraf sayısı: 10583 |Label sayısı: 10583

i=random.randint(1,10583)
print('Class:',data_label[i])
print('Görüntü boyutu:',data[i].shape)
plt.imshow(data[i]);
data=np.asarray(data)
data_label=np.asarray(data_label)
print('Araba görüntüsü yok:',len(data_label[data_label==0]),'|Araba görüntüsü var:',len(data_label[data_label==1]))

Araba görüntüsü yok: 5292 |Araba görüntüsü var: 5291

data.shape
data_label.shape

(10583, 224, 224, 3)

(10583,)

Data setinin validasyon için ayrılması:

from sklearn.model_selection import train_test_splitx_train,x_val,y_train,y_val=train_test_split(data,data_label,test_size=0.33, random_state=42)print('x_train shape:',x_train.shape)
print('x_val shape:',x_val.shape)
print('y_train shape:',y_train.shape)
print('y_val shape:',y_val.shape)

x_train shape: (7090, 224, 224, 3)

x_val shape: (3493, 224, 224, 3)

y_train shape: (7090,)

y_val shape: (3493,)

Burada görsellerin sınıflandırılması için VGG-16 pre trained(önceden eğitilmiş) modeli seçilmiştir.

base_model=tf.keras.applications.VGG16(include_top=False,input_shape=(224,224,3),weights='imagenet')model=tf.keras.Sequential()
model.add(base_model)
model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Dense(1,activation='sigmoid'))
model.summary()
base_model.trainable=False
model.compile(loss='binary_crossentropy',optimizer=tf.keras.optimizers.Adam(),metrics='accuracy')epoch=3hist=model.fit(x_train,y_train,epochs=epoch,validation_data=(x_val,y_val))
car=[]photo_path='/content/data/testing_images/vid_5_27620.jpg'
deneme_img=cv2.imread(photo_path)
ss.setBaseImage(deneme_img)
ss.switchToSelectiveSearchFast()
rects1 = ss.process()
print('Fotoğraftaki muhtemel obje sayısı: ',len(rects1))
for i in rects1:
x, y, w, h = i
bb3={'x1':x,'y1':y,'x2':x+w,'y2':y+h}
try:
assert bb3['x1'] < bb3['x2']
assert bb3['y1'] < bb3['y2']
img_data=deneme_img[bb3['y1']:bb3['y2'],bb3['x1']:bb3['x2']]
img_data=cv2.resize(img_data,(224,224))
tahmin=model.predict(img_data.reshape(1,224,224,3))
if tahmin[0]>0.5:
car.append([bb3,tahmin[0]])
else:
pass
except Exception as e:
print('hata',e)
print('kaç adet class tahmini 1 olan muhtemel bounty box var:',len(car))
print('----------------------------------------------------------')
deneme_img=cv2.imread(photo_path)
car[np.argmax(np.array(car)[:,1])][0]
pt1=(car[np.argmax(np.array(car)[:,1])][0]['x1'],car[np.argmax(np.array(car)[:,1])][0]['y1'])
pt2=(car[np.argmax(np.array(car)[:,1])][0]['x2'],car[np.argmax(np.array(car)[:,1])][0]['y2'])
plt.figure()
plt.imshow(deneme_img)
cv2.rectangle(deneme_img,pt1,pt2,(255, 0, 0),2)
plt.figure()
plt.title(f'Class numarası 1 olup ihtimal oranı en yüksek bounty box score: %{car[np.argmax(np.array(car)[:,1])][1][0]*100}')
plt.imshow(deneme_img);

--

--