deeplabv3-plus-pytorch
deeplabv3-plus-pytorch copied to clipboard
各位大佬们,谁能分享一下用C++写的后处理过程啊。
或者有没有C++后处理的开源的网址链接呢
木有木有
木有木有
@bubbliiiing 我从网上找了一堆后处理的代码,改改应该能用 ,可我改不出来。路过的大佬们 看看能不能改一改啊 例一,
const int num_classes = 1;
// 对每个像素进行后处理
void post_process(Mat& input_image, Mat& output_image, Mat& prob_map) {
int height = input_image.rows;
int width = input_image.cols;
// 对每个像素进行遍历
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// 找到概率最大的类别
int max_index = 0;
float max_prob = 0.0;
for (int k = 0; k < num_classes; k++) {
float prob = prob_map.at<float>(i, j, k);//
if (prob > max_prob) {
max_index = k;
max_prob = prob;
}
}
// 将该像素的类别设置为概率最大的类别
output_image.at<uchar>(i, j) = max_index;
}
}
}
例2:
const int OUTPUT_H = 512;
const int OUTPUT_W = 648;
const int NUM_CLASSES = 1;
void postprocess(const float* output, Mat& result)
{
result.create(OUTPUT_H, OUTPUT_W, CV_8U);
//result.create(OUTPUT_H, OUTPUT_W, CV_32SC1);
for (int i = 0; i < OUTPUT_H; ++i) {
for (int j = 0; j < OUTPUT_W; ++j) {
int idx = i * OUTPUT_W + j;
int max_idx = -1;
float max_val = -FLT_MAX;
for (int k = 0; k < NUM_CLASSES; ++k) {
float val = output[idx * NUM_CLASSES + k];
if (val > max_val) {
max_val = val;
max_idx = k;
}
}
result.at<uint8_t>(i, j) = max_idx * 100;
//result.at<int>(i, j) = max_idx * 100;
}
}
}
例三:
cv::Mat dnn_argmax(const Mat& score)
{
const int rows = score.size[2];
const int cols = score.size[3];
const int chns = score.size[1];
//存储argmax
Mat maxCl = Mat::zeros(rows, cols, CV_8UC1);
//存储max值
Mat maxVal(rows, cols, CV_32FC1, score.data);
//遍历每一个channel
for (int ch = 1; ch < chns; ch++) {
//遍历row 行
for (int row = 0; row < rows; row++) {
//--获取行指针加速内存操作
const float* ptrScore = score.ptr<float>(0, ch, row);
uint8_t* ptrMaxCl = maxCl.ptr<uint8_t>(row);
float* ptrMaxVal = maxVal.ptr<float>(row);
//遍历col 列
for (int col = 0; col < cols; col++) {
//一旦发现score中相应row,col位置的值大于maxVal,则更新maxCl和maxVal相应位置的值
if (ptrScore[col] > ptrMaxVal[col]) {
ptrMaxVal[col] = ptrScore[col];
ptrMaxCl[col] = (uchar)ch;
}
}
}
}
Mat seg2(rows, cols, CV_8UC1);//argmax结果
for (int row = 0; row < rows; row++) {
const uchar* ptrMaxCl = maxCl.ptr<uchar>(row);
uchar* ptrSeg2 = seg2.ptr<uchar>(row);
for (int col = 0; col < cols; col++) {
ptrSeg2[col] = ptrMaxCl[col];
}
}
return seg2;
}
可以参考一下这个链接
可以参考一下我写的这个
// 获取模型输出数据的指针
// unsigned char* output_data = reinterpret_cast<unsigned char*>(outputs[output_index].buf);
float* output_data = reinterpret_cast<float*>(outputs[0].buf);
// 创建一个新的整数数组来存储解释后的数据
std::vector
for (int i = 0; i < output_size/4; ++i) {
interpreted_data[i] = output_data[i];
// printf("%d, %f\n",i,interpreted_data[i]);
}
int mini_h = nh/4;
int mini_w = nw/4;
float* pr = interpreted_data.data();
// printf("interpreted_data的大小:::::%d\n",interpreted_data.size());
int slice_start_h = (output_height - mini_h) / 2;
int slice_end_h = (output_height - mini_h) / 2 + mini_h;
int slice_start_w = (output_width - mini_w) / 2;
int slice_end_w = (output_width - mini_w) / 2 + mini_w;
// 计算切片后的数据大小
int sliced_height = slice_end_h - slice_start_h;
int sliced_width = slice_end_w - slice_start_w;
int sliced_channel = output_channel;
int sliced_size = sliced_height * sliced_width*sliced_channel;
// 创建一个新的数组来存储切片后的数据
std::vector<float> sliced_data(sliced_size);
// 复制数据到新数组
for (int k = 0;k<sliced_channel;k++){
for (int i = slice_start_h; i < slice_end_h; i++) {
for (int j = slice_start_w; j < slice_end_w; j++) {
int src_index =k*output_height*output_width+ i * output_width + j;
int dst_index = k*sliced_height*sliced_width + (i - slice_start_h) * sliced_width + (j - slice_start_w);
sliced_data[dst_index] = pr[src_index];
}
}
}
pr = sliced_data.data();
// softmax操作
softmax(pr, sliced_channel, sliced_height,sliced_width);
cv::Mat segmented_img = cv::Mat(mini_h, mini_w, CV_8UC3);
std::vector<int> argmax_indices; // 存储 argmax 结果
for (int h = 0; h < sliced_height; ++h) {
for (int w = 0; w < sliced_width; ++w) {
int max_index = 0;
float max_value = pr[h * sliced_width + w];
for (int c = 1; c < output_channel; ++c) {
float current_value = pr[c*sliced_height*sliced_width+ h * sliced_width + w];
if (current_value > max_value) {
max_value = current_value;
max_index = c;
}
}
argmax_indices.push_back(max_index);
// printf("%d ",max_index);
segmented_img.at<cv::Vec3b>(h, w) = cv::Vec3b(colors[max_index][2], colors[max_index][1], colors[max_index][0]);
}
// printf("\n");
}
printf("argmax_indices大小::%d\n",argmax_indices.size());
// cv::Mat segmented_img = cv::Mat(mini_h, mini_w, CV_8UC3);
// // Map argmax_indices to colors and fill the segmented image(可优化可以直接生成mat数据)
// for (int h = 0; h < mini_h; ++h) {
// for (int w = 0; w < mini_w; ++w) {
// int index = argmax_indices[h * mini_w + w];
// segmented_img.at<cv::Vec3b>(h, w) = cv::Vec3b(colors[index][2], colors[index][1], colors[index][0]);
// }
// }
gettimeofday(&stop_time, NULL);
printf("后处理时间::once run use %f ms\n", (__get_us(stop_time) - __get_us(start_time)) / 1000);
bool saved = cv::imwrite(save_path, segmented_img);
if(saved){
std::cout<<"图片已存为:"<<save_path<<"\n\n\n\n"<<std::endl;
}
@xiaozggggg 好的 多谢 我明天研究一下
@ZJDATY 有写出来吗?分享一下?
@ZJDATY 有写出来吗?分享一下?
上面 大佬们 不是都给出来了吗
@ZJDATY xiaozggggg这个大佬的吗?你自己有实现吗?我的输出是1 * 21 * 513 * 513,下面是我推理的代码,后处理没明白,能看看不?auto input = engine->input(0); auto output = engine->tensor("output"); auto stream = engine->get_stream();
int network_width = 513;
int network_height = 513;
int image_width = rgb_image.cols;
int image_height = rgb_image.rows;
float scale = std::min(
network_width / (float)image_width,
network_height / (float)image_height
);
float affine_matrix_array[] = {
scale, 0, 0,
0, scale, 0
};
cv::Mat affine_matrix(2, 3, CV_32F, affine_matrix_array);
cv::Mat inverse_matrix;
cv::invertAffineTransform(affine_matrix, inverse_matrix);
float mean[3] = {0.485, 0.456, 0.406};
float std[3] = {0.229, 0.224, 0.225};
float* mean_ptr = nullptr;
float* std_ptr = nullptr;
float* device_inverse_matrix = nullptr;
cudaMalloc(&device_inverse_matrix, 6 * sizeof(float));
cudaMemcpyAsync(device_inverse_matrix, inverse_matrix.data, 6 * sizeof(float), cudaMemcpyHostToDevice, stream);
cudaMalloc(&mean_ptr, 3 * sizeof(float));
cudaMemcpyAsync(mean_ptr, mean, 3 * sizeof(float), cudaMemcpyHostToDevice, stream);
cudaMalloc(&std_ptr, 3 * sizeof(float));
cudaMemcpyAsync(std_ptr, std, 3 * sizeof(float), cudaMemcpyHostToDevice, stream);
auto start_time = std::chrono::high_resolution_clock::now();
cvtcolor_and_nomalize_gpu(
0,
rgb_image,
input,
device_inverse_matrix,
mean_ptr, std_ptr
);
engine->forward();
auto end_time = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
std::cout << "Inference time: " << duration.count() << " ms" << std::endl;
float* outputdata = output->cpu<float>();
好了我也自己实现了。 int height = 513; int width = 513; int num_classes = 21; cv::Mat mask(height, width, CV_8UC3); // 用于彩色mask的3通道颜色图像
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
int max_index = 0;
float max_prob = resultBuffer[h * width + w];
for (int c = 1; c < num_classes; c++) {
float prob = resultBuffer[c * height * width + h * width + w];
if (prob > max_prob) {
max_prob = prob;
max_index = c;
}
}
// 根据max_index分配颜色
cv::Vec3b color = GetColorForClass(max_index); // 实现这个函数,基于你的类别-颜色映射
mask.at<cv::Vec3b>(cv::Point(w, h)) = color;
}
}
// 保存mask
cv::imwrite("segmentation_mask.png", mask);