Вопрос или проблема
Загрузка 256 КТ-изображений 512*512 поперечных срезов и размещение их в векторе<mat>(256),
Handler(std::string path) {
pixel_array.reserve(slice_num);
for (int i = 0; i < slice_num; i++) {
std::ostringstream oss;
oss << path << i << ".png";
cv::Mat img = cv::imread(oss.str(),cv::IMREAD_UNCHANGED);//это изображение имеет 16-битную глубину цвета
if (img.empty()) {
std::cerr << "Не удалось загрузить изображение: " << oss.str() << std::endl;
}
else
{
pixel_array.push_back(img);//добавить изображение в вектор
}
}
}
затем получение корональных и сагиттальных срезов с помощью следующего кода:
// Получить корональный срез
std::vector<cv::Mat> get_coronal() {
std::vector<cv::Mat> coronal_section(slice_height, cv::Mat(slice_num, slice_width, CV_16UC1, cv::Scalar(0)));
for (int i = 0; i < slice_height; i++)
{
for (int k = 0; k < slice_num; k++)
{
pixel_array[k].row(i).copyTo(coronal_section[i].row(k));
}
}
return coronal_section;
}
// Получить сагиттальный срез
std::vector<cv::Mat> get_sagittal() {
std::vector<cv::Mat> sagittal_section(slice_width, cv::Mat(slice_height, slice_num, CV_16UC1, cv::Scalar(0)));
for (int j = 0; j < slice_width; j++)
{
for (int k = 0; k < slice_num; k++)
{
pixel_array[k].col(j).copyTo(sagittal_section[j].col(k));
}
}
return sagittal_section;
}
//получить поперечный срез
std::vector<cv::Mat> get_transverse()
{
return pixel_array;
}
Я использовал imshow для отображения поперечных, корональных и сагиттальных срезов, но корональные и сагиттальные срезы не удавалось корректно отобразить. Я попытался изменить их типы данных вектора на (CV_8UC1), но результаты стали еще хуже. Подозреваю, что может быть проблема с процессом копирования данных.это результат。ниже показано, как я использую imshow для этих изображений(девяносто первый срез)
void showslice()
{
std::vector<cv::Mat>transverse(slice_num), cornoal(slice_height), sagittal(slice_width);
transverse = get_transverse();
cornoal = get_coronal();
sagittal = get_sagittal();
cv::namedWindow("transverse", cv::WINDOW_AUTOSIZE);
cv::namedWindow("coronal", cv::WINDOW_AUTOSIZE);
cv::namedWindow("sagittal", cv::WINDOW_AUTOSIZE);
cv::imshow("transverse", transverse[90]);
cv::imshow("coronal", cornoal[90]);
cv::imshow("sagittal", sagittal[90]);
}
после изменения двух функций изображение отображается корректно.
std::vector<cv::Mat> get_coronal() {
std::vector<cv::Mat> coronal_section(slice_width);
for (int i = 0; i < slice_width; i++) {
cv::Mat slice(slice_num, slice_height, CV_16UC1);
for (int j = 0; j < slice_num; j++) {
pixel_array[j].row(i).copyTo(slice.row(j));
}
coronal_section[i] = slice;
}
return coronal_section;
}
std::vector<cv::Mat> get_sagittal() {
std::vector<cv::Mat> sagittal_section(slice_height);
for (int i = 0; i < slice_height; i++) {
cv::Mat slice(slice_width,slice_num , CV_16UC1);
for (int j = 0; j < slice_num; j++) {
pixel_array[j].col(i).copyTo(slice.col(j));
}
sagittal_section[i] = slice;
}
return sagittal_section;
}
Ответ или решение
Ваша проблема с неправильным отображением корональных и сагиттальных срезов из вектора 256 КТ изображений может быть связана с несколькими аспектами вашего кода и логики обработки изображений. Рассмотрим эти аспекты подробно, чтобы выявить возможные источники ошибок и предложить эффективные решения.
1. Неправильное создание и заполнение новых матриц
Первое, что стоит отметить, — это создание матриц для хранения корональных и сагиттальных срезов. В вашем изначальном коде get_coronal()
и get_sagittal()
, вы создавали векторы, которые не полностью соответствовали требуемым параметрам.
Корональные срезы
Ваш изначальный фрагмент кода:
std::vector<cv::Mat> get_coronal() {
std::vector<cv::Mat> coronal_section(slice_height, cv::Mat(slice_num, slice_width, CV_16UC1, cv::Scalar(0)));
в нем выделялось место для slice_height
матриц, каждая из которых имела размер slice_num x slice_width
. В результате coronal_section[i]
фактически содержал пустую матрицу, что неприемлемо для последующей обработки.
Исправленный код
В исправленных функциях вы корректно объявляете матрицы для корональных и сагиттальных срезов. В каждом цикле for
, куда вы заполняете эти матрицы, это помогает создать полноценные 2D представления срезов:
std::vector<cv::Mat> get_coronal() {
std::vector<cv::Mat> coronal_section(slice_width);
for (int i = 0; i < slice_width; i++) {
cv::Mat slice(slice_num, slice_height, CV_16UC1);
for (int j = 0; j < slice_num; j++) {
pixel_array[j].row(i).copyTo(slice.row(j));
}
coronal_section[i] = slice;
}
return coronal_section;
}
Такой подход способствует корректному заполнению матриц.
2. Обработка данных с 16-битной глубиной цвета
Проблема может быть также связана с тем, что у ваших изображений есть 16-битная глубина цвета, а OpenCV по умолчанию может не поддерживать 16-битные изображения в случае некоторых операций. Использование CV_8UC1
для преобразования может привести к потере информации, так как диапазон значений 16-битного изображения (0-65535) не может корректно быть представлен в 8-битном (0-255).
Рекомендуется оставить целочисленные матрицы 16-битные (CV_16UC1
), и обработать данные с учетом этой глубины.
3. Проверка параметров при отображении
Когда вы используете imshow
для отображения корональных и сагиттальных срезов, необходимо удостовериться, что индекс 90
, который вы используете для доступа к элементам вектора, не превышает количество доступных срезов в массиве. Например, если размер вектора срезов меньше 91 (например, если у вас только 90 срезов), это приведет к обращению к недоступной памяти.
4. Итоговая структура и оптимизация
Чтобы избежать дальнейших ошибок, предварительно проверьте размеры и типы данных каждого изображения после их загрузки. Кроме того, разумно вести логи для отслеживания любых ошибок, которые могли бы возникнуть в процессе обработки изображений.
Примерно вот так:
if (img.type() != CV_16UC1) {
std::cerr << "Image format error at: " << oss.str() << std::endl;
}
Это поможет в диагностике.
Заключение
Таким образом, исправив логику создания и заполнения матриц для корональных и сагиттальных срезов, удостоверившись в правильной передаче типов данных и обратив внимание на индексы при отображении, вы сможете корректно генерировать и отображать необходимые срезы КТ. Применение данных рекомендаций должно значительно улучшить качество и точность представления ваших медицинских изображений.