Эта статья предназначена как для начинающих, так и для экспертов в области компьютерного зрения. Я надеюсь, что этот пост воздаст должное ” .
Проблема
У нас уже есть датчики движения, которые легко справляются с подобными задачами, но если мы хотим использовать компьютерное зрение, все становится сложнее. Как получить скорость только с помощью картинок, поначалу может показаться невозможным, но после прочтения этого, надеюсь, все станет лучше.
Подход
Для этого нам нужно выполнить следующие действия
- Отправьте два изображения в наше приложение – очевидно 😂
- Найдите разницу между двумя изображениями
- Вычислите 🚗 💨 по разнице в изображениях
Звучит довольно просто, не так ли? Позволь мне отвезти тебя на 🎢
Загружайте Изображения В Наше Приложение
Мы используем класс BufferedImage по умолчанию, предоставляемый JAVA, для чтения файлов с указанными путями.
Реализация
BufferedImage image1 = ImageIO.read(new File(img1)); BufferedImage image2 = ImageIO.read(new File(img2));
Первое изображение Второе изображение
Вычитание Изображения, Чтобы Получить Разницу
Теперь, когда у нас есть два изображения, мы выполняем вычитание изображений. Возможно, вам интересно, что такое вычитание изображений. Изображения в значительной степени представляют собой массив из множества значений пикселей, которые были объединены вместе. Вычитание изображения в простейших терминах – это Нахождение разницы между каждым пикселем на изображении и соответствующим пикселем на другом изображении. Чтобы выполнить вычитание изображения, оба изображения должны иметь одинаковое разрешение ( поскольку мы вычитаем каждый пиксель в одном из другого ). Когда мы вычитаем изображение, мы устанавливаем пороговое значение и устанавливаем любое значение пикселя выше порогового значения на ЧЕРНЫЙ, а значения пикселей ниже порогового значения на БЕЛЫЙ ( Мы делаем это, потому что хотим видеть автомобили в черном цвете после вычитания изображений )
Реализация
public BufferedImage ImageSubtract(BufferedImage img1 , BufferedImage img2){ int imageheight = img1.getHeight(); int imagewidth = img1.getWidth(); WritableRaster image1 = img1.getRaster(); WritableRaster image2 = img2.getRaster(); // pixel values have their, red , green and blue components int diffred; int diffblue; int diffgreen; // set threshold for subtraction Color treshold = new Color(30,30,30); // Create an empty image BufferedImage DiffImage = new BufferedImage(imagewidth,imageheight,BufferedImage.TYPE_INT_RGB); for(int y = 0 ; y < imageheight ; y++){ for( int x = 0 ; x < imagewidth ; x++){ diffred = Math.abs( image1.getSample(x, y, 0) - image2.getSample(x,y,0)); diffgreen = Math.abs(image2.getSample(x,y,1) - image1.getSample(x, y, 1)); diffblue = Math.abs(image2.getSample(x,y,2) - image1.getSample(x, y, 2)); // combine individual rgb components to give one color Color diff = new Color(diffred,diffgreen,diffblue); DiffImage.setRGB(x, y, diff.getRGB()); // to visualize the differences in the image if(DiffImage.getRGB(x, y) < treshold.getRGB()){ diff= Color.WHITE; DiffImage.setRGB(x, y,diff.getRGB()); } else{ diff = Color.BLACK; DiffImage.setRGB(x,y,diff.getRGB()); } } } try { // write the result image to a file ImageIO.write(DiffImage,"jpg",new File("MotionDetected.jpg")); } catch (IOException e) { e.printStackTrace(); } return DiffImage; }
Изображение результата
Расчет Скорости По Изображению Разница
Теперь, когда мы визуализировали разницу, пришло время для “веселой” части 🕺🏾 . Получение скорости по изображению. Для этого мы применили некоторую забавную логику Отказ от ответственности: Возможно, есть лучший способ реализовать это, но я искал метод, который наиболее легко объяснить
Мы просматриваем изображение “разница”, а затем выбираем первый найденный черный пиксель и сохраняем его. Затем мы снова просматриваем изображение “разница”, а затем выбираем последний черный пиксель, который мы находим.
Теперь придется сделать некоторые предположения
- Время, прошедшее между первой и второй картинкой, скажем, 5 секунд
- Предполагаемое увеличение камеры, используемой для съемки снимков
- Длина автомобиля в миллиметрах (скажем, 6000 мм)
Как только эти предположения сделаны, мы затем уменьшаем длину автомобиля в пикселях, чтобы упростить жизнь, а затем перемещаем расстояние, distance_moved.abs(x2 - x1) - car_length_in_px;
Мы вычли длину автомобиля в пикселях, потому что расстояние перемещено от передней части автомобиля. Затем мы решаем для скорости скорость = ((двойное) расстояние перемещено/прошло время;
Более подробная информация ниже
Реализация
public double SpeedCalc(BufferedImage img){ double speed = 0.0; int x1 = 0; int x2 = 0; WritableRaster newImg = img.getRaster(); for(int y = 0; y< img.getHeight(); y++){ for(int x = 0; x < img.getWidth(); x++){ if( newImg.getSample(x, y, 0)== 0){ x1 = x; // thats the the first x black value break; } else{ continue; } } if(x1 > 0){ break; } } for(int y=0; y< img.getHeight(); y++){ for(int x = 0; x
Результаты
$ java MotionDetection images/car_moving_final_1.PNG images/car_moving_final_2.PNG The resulting difference of the image is stored in MotionDetected.jpg Time Passed between 2 images 7 seconds Final Position of Car:370, Initial Position of Car:1311 Speed of car is 0.63 metres/second
Вот ссылка на репозиторий github, если вы хотите увидеть полный исходный код https://github.com/oreHGA/Speed-Detector
Спасибо, что поехали со мной! Ре’Ре¾”Ре’»
Оригинал: “https://dev.to/ore/detecting-speed-of-a-car-from-two-images”