Как отфильтровать цвета из 16-битных значений из файла .las? - PullRequest
1 голос
/ 28 апреля 2020

У меня есть .las файл с содержимым, например:

   array([( 860297,  472942, 67187, 11051, 73, 0, 0, 0, 1, 12079, 11051,  9252),
           ( 859318,  473132, 67336,  8995, 73, 0, 0, 0, 1,  9252,  8995,  9509),
           ( 859941,  473665, 67550, 12079, 73, 0, 0, 0, 1, 12079, 12850, 10023),
           ...,
           (1057593, 1184341, 75212, 19018, 73, 0, 0, 0, 1, 20303, 19275, 16191),
           (1057764, 1184161, 74734, 14906, 73, 0, 0, 0, 1, 15934, 14906, 13878),
           (1057548, 1184058, 74881, 26214, 73, 0, 0, 0, 1, 28784, 25957, 21074)],
          dtype=[('X', '<i4'), ('Y', '<i4'), ('Z', '<i4'), ('intensity', '<u2'), ('bit_fields', 'u1'),
                 ('raw_classification', 'u1'), ('scan_angle_rank', 'i1'), ('user_data', 'u1'),
                 ('point_source_id', '<u2'), ('red', '<u2'), ('green', '<u2'), ('blue', '<u2')])

Как я обнаружил в файлах .las, значения в RGB хранятся в 16-битных цветах. Я написал 2 функции - преобразовать цвета в 8-битные:

opened_file = open("my.las") #example
colors = opened_file.points[["red", "green", 'blue']]
>>> array([(12079, 11051,  9252), (9252,  8995,  9509), (12079, 12850, 10023), ...])

def eightbitify(colour):
    return colour/256

Далее я пытаюсь преобразовать цвета в HSV, поэтому у меня будет возможность отфильтровать указанные c цвета:

def to_hsv(rgb: np.ndarray):
    empty_image = np.zeros((1, 1, 3), dtype=np.uint8)
    empty_image[0, 0] = list(reversed(rgb))
    hsv = cv2.cvtColor(empty_image, cv2.COLOR_RGB2HSV)
    return list(reversed(hsv[0, 0]))

Мне не удалось найти лучшего решения для этого, потому что OpenCV нужно изображение - поэтому я создаю изображение для 1 пикселя и конвертирую его (так уродливо: /). Проблема в том, что значения, которые я получаю, не совпадают ни с одним из результатов вычислений inte rnet RGB-HSV. Я использую эти функции следующим образом:

def convert_color(rgb_16: np.ndarray)->np.ndarray:
    converted_color = np.array([int(eightbitify(rgb_16[0])), int(eightbitify(rgb_16[1])), int(eightbitify(rgb_16[2]))])
    converted_hsv = to_hsv(converted_color)
    return converted_hsv

for color in colors:
    converted = convert_color(color)

Итак, мои вопросы:
1. Каков наилучший способ преобразования значений RGB в HSV из моего opened_file.points исходного массива?
2. Как отфильтровать определенные c цвета из моего opened_file.points только с использованием numpy? Может быть, я могу применить некоторую функцию преобразования к значениям RGB и т. Д. c?
К сожалению, у меня очень небольшой опыт работы с numpy, поэтому мне нужна помощь. Спасибо!

1 Ответ

1 голос
/ 28 апреля 2020

Я не знаком с вашим типом изображения, но, надеюсь, могу помочь вам с аспектами Numpy и OpenCV.

#!/usr/bin/env python3

import pylas
import cv2
import numpy as np

# Open file
las = pylas.read('W2.las')

# Extract all the red values into a Numpy array, likewise green and blue
R = las.points["red"]
G = las.points["green"]
B = las.points["blue"]

# Make a Numpy image by stacking the RGB values and converting to uint8
BGR = (np.dstack((B,G,R))>>8).astype(np.uint8)

# Convert to HSV
HSV = cv2.cvtColor(BGR, cv2.COLOR_BGR2HSV)

# Define lower and uppper limits of what we call "green"
range_lo = np.array([70,30,30])
range_hi = np.array([90,255,255])

# Mask image to only select greens
mask = cv.inRange(HSV,range_lo,range_hi)

# Change image to red where we found green
image[mask>0]=(0,0,255)

cv.imwrite("result.png",image)

В настоящее время я не знаю форму изображения, поэтому он получается длинной строкой в ​​44 миллиона пикселей, но для его исправления требуется reshape(). Обратите внимание, что каждое значение True / False в mask будет индексом в вашем списке пикселей и указывает, является ли этот пиксель зеленым или нет.

Возможно, вам придется работать с нижним и верхним значениями * Параметр 1008 * - см. Мой ответ здесь .

Пользователь переполнения стека @nathancy сделал довольно аккуратный селектор цвета HSV с ползунками здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...