Эта статья предназначена как для начинающих, так и для экспертов в области компьютерного зрения. Я надеюсь, что этот пост воздаст должное ” .
Проблема
У нас уже есть датчики движения, которые легко справляются с подобными задачами, но если мы хотим использовать компьютерное зрение, все становится сложнее. Как получить скорость только с помощью картинок, поначалу может показаться невозможным, но после прочтения этого, надеюсь, все станет лучше.
Подход
Для этого нам нужно выполнить следующие действия
- Отправьте два изображения в наше приложение – очевидно 😂
- Найдите разницу между двумя изображениями
- Вычислите 🚗 💨 по разнице в изображениях
Звучит довольно просто, не так ли? Позволь мне отвезти тебя на 🎢
Загружайте Изображения В Наше Приложение
Мы используем класс 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”