You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
3.5 KiB
98 lines
3.5 KiB
4 years ago
|
import cv2
|
||
|
import numpy as np
|
||
|
import keras
|
||
|
|
||
|
'''
|
||
|
задачи
|
||
|
1) находить контур цифры
|
||
|
2) получать его координаты, вывести отдельным изображением
|
||
|
3) масштабировать его под нужный размер
|
||
|
4) загнать это на нейронную сеть https://habr.com/ru/post/466565/
|
||
|
5) вывести результат
|
||
|
|
||
|
очень сильно шумит изображение
|
||
|
'''
|
||
|
|
||
|
|
||
|
def find_number(frame):
|
||
|
# функция выполняет предобработку изображения
|
||
|
# находит область с цифрой по контурам
|
||
|
# далее в цикле перебераем найденные контуры
|
||
|
# если контур найден, то меняем разрешение на 28*28
|
||
|
# выполняем бинаризацию, делим на 255 и инвертируем вычитая 1
|
||
|
# flag нужен, чтобы он не выводил единицу, если цифра не найдена
|
||
|
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
||
|
blur = cv2.GaussianBlur(gray,(3,3), 0)
|
||
|
edges = cv2.Canny(blur, 50, 100)
|
||
|
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||
|
img2 = np.zeros((28, 28), np.uint8)
|
||
|
img_rec = np.zeros((1, 28, 28, 1), np.uint8)
|
||
|
fail = True
|
||
|
|
||
|
for contr in contours:
|
||
|
|
||
|
if cv2.contourArea(contr) < 500:
|
||
|
continue
|
||
|
x,y,w,h = cv2.boundingRect(contr)
|
||
|
img2 = frame[y-5:y+h+5, x-5:x+w+5]
|
||
|
|
||
|
# Проверка на некорректное изображение
|
||
|
if img2.shape[0] <= 0 or img2.shape[1]<= 0:
|
||
|
continue
|
||
|
|
||
|
#Фильтер по вертикальности рамки
|
||
|
if img2.shape[0] < img2.shape[1]:
|
||
|
continue
|
||
|
|
||
|
img2 = cv2.resize(img2, (28, 28))
|
||
|
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
|
||
|
|
||
|
# th3 = cv2.adaptiveThreshold(img2,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
|
||
|
# cv2.THRESH_BINARY,11,2)
|
||
|
|
||
|
_, th3 = cv2.threshold(img2,127,255,cv2.THRESH_BINARY)
|
||
|
|
||
|
# Фильтруем по следнему цвету, должно быть много белого
|
||
|
avg_color_per_row = np.average(th3, axis=0)
|
||
|
avg_color = np.average(avg_color_per_row, axis=0)
|
||
|
if avg_color < 180:
|
||
|
continue
|
||
|
|
||
|
# Если все норм то рисуем рамки на исходном изображении.
|
||
|
img = cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
|
||
|
|
||
|
cv2.imshow("img2", img2)
|
||
|
cv2.imshow("th3", th3)
|
||
|
|
||
|
img_rec = th3/255.0
|
||
|
img_rec = 1 - img_rec
|
||
|
img_rec = img_rec.reshape((1,28,28,1))
|
||
|
|
||
|
fail = False
|
||
|
return img2, img_rec, fail
|
||
|
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
cam = cv2.VideoCapture(0)
|
||
|
model = keras.models.load_model('mnist_trained_model.h5')
|
||
|
try:
|
||
|
while True:
|
||
|
_, frame = cam.read()
|
||
|
img_show, img_rec, fail = find_number(frame)
|
||
|
if fail == False:
|
||
|
result = model.predict_classes([img_rec])
|
||
|
cv2.putText(frame,str(result[0]),(10,460), cv2.FONT_HERSHEY_SIMPLEX, 1,(0,0,255),2,cv2.LINE_AA)
|
||
|
|
||
|
|
||
|
cv2.imshow("Image", frame)
|
||
|
|
||
|
k = cv2.waitKey(2)
|
||
|
if k == 27:
|
||
|
#cv2.imwrite('diff_robot_nn/nine.jpg', img_show)
|
||
|
cv2.destroyAllWindows()
|
||
|
break
|
||
|
except Exception as e:
|
||
|
cam.release()
|
||
|
cv2.destroyAllWindows()
|
||
|
print(e)
|