#c #tiff #dijkstra #slam
#c #tiff #dijkstra #хлопнуть
Вопрос:
Я работаю с SLAM для создания среды. Я делаю это с помощью лидарного датчика, и он работает довольно круто. Теперь у меня есть карта среды в формате .tiff. Я хочу найти кратчайший путь (Дейкстра) из точки A в B, но моя проблема в том, что я не знаю, как преобразовать эту карту .tiff в формат, с которым я могу работать. Я пишу на C .
У кого-нибудь есть идеи, как я мог бы это сделать?
Спасибо 🙂
Редактировать:
Карта выглядит следующим образом. Черные пиксели — это препятствия, а серые — пространство для перемещения.
Комментарии:
1. Что именно представляет собой содержимое этого изображения в формате TIFF? Можете ли вы опубликовать пример?
2. Да, большое вам спасибо. Извините, я новичок в этом сообществе и еще не знаю всех правил.
Ответ №1:
Я бы рекомендовал вам использовать CImg
— link здесь . Это C , очень легкий и простой в использовании, поскольку он реализован как «только заголовок» — так что вы просто загружаете и включаете один файл CImg.h
, и все готово.
Этот код прочитает вашу карту TIF и позволит вам получить доступ к пикселям:
#include <iostream>
#include "CImg.h"
using namespace std;
using namespace cimg_library;
int main(int argc, char** const argv)
{
// Load the map
CImg<unsigned char> map("map.tif");
// Get and print its dimensions
int w = map.width();
int h = map.height();
cout << "Dimensions: " << w << "x" << h << endl;
// Iterate over all pixels displaying their RGB values
for (int r = 0; r < h; r ){
for (int c = 0; c < w; c ){
cout << r << "," << c << "=" << (int)map(c,r,0,0) << "/" << (int)map(c,r,0,1) << "/" << (int)map(c,r,0,2) << endl;
}
}
return 0;
}
Пример вывода
Dimensions: 400x300
0,0=94/94/94
0,1=100/100/100
0,2=88/88/88
0,3=89/89/89
0,4=89/89/89
0,5=89/89/89
0,6=89/89/89
0,7=89/89/89
0,8=89/89/89
0,9=89/89/89
0,10=89/89/89
0,11=89/89/89
0,12=89/89/89
0,13=89/89/89
0,14=89/89/89
0,15=93/93/93
0,16=101/101/101
....
....
Установите такие флаги компиляции, чтобы включить встроенную поддержку (без ImageMagick) для TIFF:
g -Dcimg_use_tiff ... -ltiff
Вам нужно будет установить lib tiff
.
Если вас не интересует цвет, вы можете преобразовать изображение в черно-белое, чтобы это был всего лишь один канал, а не три, и пороговое значение, чтобы у вас были только чистые черные и чистые белые цвета, с которыми может быть легче иметь дело. Просто добавьте этот код в конец приведенного выше кода:
// Convert to single channel black and white
CImg<unsigned char> bw = map.get_RGBtoYCbCr().channel(0);
bw.normalize(0,255).threshold(1).normalize(0,255);
// Now get pointer to black and white pixels, or use bw(x,y,0)
unsigned char* data=bw.data();
bw.save_png("result.png");
На самом деле есть dijkstra
метод, CImg
но я не могу понять, как его использовать в данный момент — если кто-нибудь знает, пожалуйста, отметьте меня в комментарии! Спасибо.
Комментарии:
1. Классный пример и здорово узнать о CImg.
2. @BruceDean Спасибо, добрый сэр!
Ответ №2:
В качестве альтернативы, если вам разрешено изменять свои данные «перед полетом», вы можете использовать ImageMagick для преобразования вашего файла TIFF в чрезвычайно простой файл PGM. ImageMagick установлен в большинстве дистрибутивов Linux и доступен для OSX и Windows.
Формат PGM очень прост и описан здесь . Поскольку ваше изображение имеет размер 400×300, оно будет выглядеть следующим образом:
P5
400 300
255
120,000 unsigned char bytes of image data - uncompressed, unpadded
Вы бы преобразовали свой файл TIFF следующим образом:
convert map.tif -normalize -threshold 1 map.pgm
и затем вы можете прочитать 3 строки заголовка, а затем напрямую прочитать ваши 120 000 байт в массив. Таким образом, вам не нужны дополнительные библиотеки или программное обеспечение на вашей платформе.