fcn训练及预测tgs数据集
一、背景
kaggle上有这样一个题目,关于盐份预测的语义分割题目。TGS Salt Identification Challenge | Kaggle https://www.kaggle.com/c/tgs-salt-identification-challenge
二、过程
1、下载数据,https://www.kaggle.com/c/tgs-salt-identification-challenge/data
数据说明:
train.csv
id rle_mask
4000项,即有4000张图片 depths.csv
id z
z(地下深度,英尺)
22000项(为train和test图片张数总和)
[50, 959] test
18000张图片 sample_submission.csv
5f3b26ac68,1 2626 2628 100
数据从1开始,行数和列数都要调整为从1开始,
对于python来说,不需要转置,对于opencv来说要转置
数据处理:
(1)对于每张拍摄好的原始图片,有对应的深度信息,为了方便fcn训练,我们把深度信息也存入到图片中。可以用opencv将已标注好的原图,和带预测的原图的b通道保存原来的灰度信息,将g通道保存depth/256(整数倍),将r通道保存depth%256(取余数)。
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <hash_map> int split(std::string str, std::string pattern, std::vector<std::string> &words)
{
std::string::size_type pos;
std::string word;
int num = 0;
str += pattern;
std::string::size_type size = str.size();
for (auto i = 0; i < size; i++) {
pos = str.find(pattern, i);
if (pos == i) {
continue;//if first string is pattern
}
if (pos < size) {
word = str.substr(i, pos - i);
words.push_back(word);
i = pos + pattern.size() - 1;
num++;
}
}
return num;
} int main(int argc, char** argv)
{
std::string input_path = "E:\\kaggle\\competition\\tgs\\test_images\\";
std::string out_path = "E:\\kaggle\\competition\\tgs\\test_images_out\\";
//read image name
std::ifstream fin(input_path + "filelist.txt");
std::string line;
std::vector<std::string> image_names;
while (!fin.eof()) {
std::getline(fin, line);
image_names.push_back(line);
//std::cout << line << std::endl;
//getchar();
} std::ifstream depth_file("E:\\kaggle\\competition\\tgs\\depths.csv");
std::getline(depth_file, line);
//std::vector<int> depths;
std::map<std::string, int> depths;
while (!depth_file.eof()) {
std::getline(depth_file, line);
std::vector<std::string> words;
int ret = split(line, ",", words);
if (ret == 2) {
//depths.push_back(atoi(words[1].c_str()));
//std::cout << "depth " << depths[depths.size() - 1] << std::endl;
//getchar();
depths[words[0]] = atoi(words[1].c_str());
//std::cout << words[0] << ": " << depths[words[0]] << std::endl;
//getchar();
}
}
std::cout << "depths size = " << depths.size() << std::endl; //read image
for (int i = 0; i < image_names.size(); ++i) {
std::cout << "i = " << i << std::endl;
cv::Mat src = cv::imread(input_path + image_names[i] + ".png", cv::IMREAD_GRAYSCALE);
if (src.empty()) {
return -1;
}
cv::Mat dst = cv::Mat::zeros(src.size(), CV_8UC3);
for (int r = 0; r < dst.rows; ++r) {
uchar *sptr = src.ptr<uchar>(r);
cv::Vec3b *ptr = dst.ptr<cv::Vec3b>(r);
for (int c = 0; c < dst.cols; ++c) {
ptr[c][0] = sptr[c];
ptr[c][1] = depths[image_names[i]] / 256;
ptr[c][2] = depths[image_names[i]] % 256;
}
}
cv::imwrite(out_path + image_names[i] + ".png", dst);
} std::cout << "finish!" << std::endl;
getchar();
return 0;
}
更改输入输出路径,对于已标注好的原图片用同样的方式处理。
(2)因为我们的题目是二分类的语义分割,所以分割的结果的label只能是0和1,所以必须将masks中的图片为255更改为1。
int main(int argc, char** argv)
{
//read image name
std::ifstream fin("filelist.txt");
std::string line;
std::vector<std::string> image_names;
while (!fin.eof()) {
std::getline(fin, line);
image_names.push_back(line);
} //modify value
for (int num = 0; num < image_names.size(); ++num) {
cv::Mat src;
src = cv::imread("masks/" + image_names[num], -1);
if (src.empty()) {
std::cout << "fail: " << num << image_names[num] << std::endl;
getchar();
return -1;
} cv::Mat dst;
src.convertTo(dst, CV_8UC1);
for (int j = 0; j < dst.rows; ++j) {
uchar *ptr = dst.ptr<uchar>(j);
for (int i = 0; i < dst.cols; ++i) {
if (ptr[i] >= 128) {
ptr[i] = 1;
}
}
}
cv::imwrite("out/" + image_names[num], dst);
}
}
也可直接下载处理好的图片:链接:https://pan.baidu.com/s/1CAPIvQ6PayZ97eqeTpBcow 密码:h3t9
2、下载语义分割的开源代码
shelhamer/fcn.berkeleyvision.org: Fully Convolutional Networks for Semantic Segmentation by Jonathan Long*, Evan Shelhamer*, and Trevor Darrell. CVPR 2015 and PAMI 2016. https://github.com/shelhamer/fcn.berkeleyvision.org
3、下载修改好的代码
https://github.com/litingpan/fcn
4、将tgs-fcn32s、tgs-fcn16s、tgs-fcn8s复制到fcn.berkeleyvision.org文件夹中,将data/tgs复制到fcn.berkeleyvision.org/data文件夹中,将1中处理好的数据拷贝至tgs对应文件夹中。
5、训练
(1)fcn32s训练
fcn.berkeleyvision.org\tgs-fcn32s>python solve.py

(2)训练fcn16s
fcn.berkeleyvision.org\tgs-fcn16s>python solve.py

(3)训练fcn8s
fcn.berkeleyvision.org\tgs-fcn8s>python solve.py

可以看到经过32倍、16倍、8倍上采样最终达到overall accuracy(总体精度)为0.928,mean accuracy(平均精度)为0.887,mean IU(平均交并比)为0.827,fwavacc(带权重交并比)为0.866。
6、预测
我们用fcn8s训练好的模型进行预测。
fcn.berkeleyvision.org\tgs-fcn8s>python infers.py
输出的结果在fcn.berkeleyvision.org\data\tgs\predict\masksout文件夹中,因为值是不是0就是1,所以感觉图片都是黑色的,如果想要可视化可以用opencv将1改为255,重新保存图片。
7、将预测结果存到csv文件中。
int main(int argc, char** argv)
{
//read image name
std::ifstream fin("masksout/filelist.txt");
std::string line;
std::vector<std::string> image_names;
while (!fin.eof()) {
std::getline(fin, line);
image_names.push_back(line);
} std::ofstream fout("submission.csv");
fout << "id,rle_mask" << std::endl;
for (int k = 0; k < image_names.size(); ++k) {
std::cout << "k = " << k << std::endl;
cv::Mat src = cv::imread("masksout/" + image_names[k]); if (src.empty()) {
return -1;
} fout << image_names[k].substr(0, image_names[k].size()-4) << ",";
cv::Mat gray;
cv::cvtColor(src, gray, CV_BGR2GRAY); cv::Mat trans;
cv::transpose(gray, trans); //fill hole
cv::Mat tmp;
cv::Mat hole;
trans.convertTo(tmp, CV_8UC1, 255);
dip::fillHole(tmp, hole); bool flag = false;
int sum = 0;
std::vector<int> list;
int start_id = 0;
for (int j = 0; j < src.rows; ++j) {
uchar *ptr = hole.ptr<uchar>(j);
for (int i = 0; i < src.cols; ++i) { if (ptr[i] && !flag) {
flag = true;
start_id = j*gray.rows + i+1;
sum = 0;
sum++;
}
else if (ptr[i] && flag) {
sum++;
}
else if (!ptr[i] && flag){
flag = false;
list.push_back(start_id);
list.push_back(sum);
//std::cout << "start_id = " << start_id << ", " << "sum = " << sum << std::endl;
//getchar();
}
}
}//for j
for (int n = 0; n < list.size(); ++n) {
if (n == 0) {
fout << list[0];
}
else {
fout << " " << list[n];
}
}
fout << std::endl;
if (list.size() % 2 != 0) {
std::cout << "error " << image_names[k] << std::endl;
} }
std::cout << "finish!" << std::endl;
getchar();
return 0;
}
其中fillHole函数为
namespace dip {
void fillHole(const cv::Mat &src, cv::Mat &dst)
{
cv::Size sz = src.size();
cv::Mat tmp = cv::Mat::zeros(sz.height + 2, sz.width + 2, src.type());
src.copyTo(tmp(cv::Range(1, sz.height + 1), cv::Range(1, sz.width + 1)));
cv::floodFill(tmp, cv::Point(0, 0), cv::Scalar(255));
cv::Mat cut;
tmp(cv::Range(1, sz.height + 1), cv::Range(1, sz.width + 1)).copyTo(cut);
dst = src | (~cut);
}
}
8、提交结果

看来这个结果离比赛要求的答案还差很远。
end
fcn训练及预测tgs数据集的更多相关文章
- Alink漫谈(七) : 如何划分训练数据集和测试数据集
Alink漫谈(七) : 如何划分训练数据集和测试数据集 目录 Alink漫谈(七) : 如何划分训练数据集和测试数据集 0x00 摘要 0x01 训练数据集和测试数据集 0x02 Alink示例代码 ...
- 万字长文,以代码的思想去详细讲解yolov3算法的实现原理和训练过程,Visdrone数据集实战训练
以代码的思想去详细讲解yolov3算法的实现原理和训练过程,并教使用visdrone2019数据集和自己制作数据集两种方式去训练自己的pytorch搭建的yolov3模型,吐血整理万字长文,纯属干货 ...
- ResNet网络的训练和预测
ResNet网络的训练和预测 简介 Introduction 图像分类与CNN 图像分类 是指将图像信息中所反映的不同特征,把不同类别的目标区分开来的图像处理方法,是计算机视觉中其他任务,比如目标检测 ...
- 『计算机视觉』Mask-RCNN_训练网络其一:数据集与Dataset类
Github地址:Mask_RCNN 『计算机视觉』Mask-RCNN_论文学习 『计算机视觉』Mask-RCNN_项目文档翻译 『计算机视觉』Mask-RCNN_推断网络其一:总览 『计算机视觉』M ...
- 机器学习使用sklearn进行模型训练、预测和评价
cross_val_score(model_name, x_samples, y_labels, cv=k) 作用:验证某个模型在某个训练集上的稳定性,输出k个预测精度. K折交叉验证(k-fold) ...
- 初识Sklearn-IrisData训练与预测
笔记:机器学习入门---鸢尾花分类 Sklearn 本身就有很多数据库,可以用来练习. 以 Iris 的数据为例,这种花有四个属性,花瓣的长宽,茎的长宽,根据这些属性把花分为三类:山鸢尾花Setosa ...
- Spark技术在京东智能供应链预测的应用——按照业务进行划分,然后利用scikit learn进行单机训练并预测
3.3 Spark在预测核心层的应用 我们使用Spark SQL和Spark RDD相结合的方式来编写程序,对于一般的数据处理,我们使用Spark的方式与其他无异,但是对于模型训练.预测这些需要调用算 ...
- 吴裕雄 python 神经网络——TensorFlow 使用卷积神经网络训练和预测MNIST手写数据集
import tensorflow as tf import numpy as np from tensorflow.examples.tutorials.mnist import input_dat ...
- siftflow-fcn32s训练及预测
一.说明 SIFT Flow 是一个标注的语义分割的数据集,有两个label,一个是语义分类(33类),另一个是场景标签(3类). Semantic and geometric segmentatio ...
随机推荐
- ASP.NET MVC4应用程序配置跨域访问
开发框架是使用webapi做后台,HTML5做前台,通过ajax调用webapi后台,返回json结果. 用的编译器是visual Studio2013,下面是配置方法 1.web.config文件 ...
- My SQL随记 003 数据表基础操作语法
数据表 查看数据表 修改表名 修改字段名 修改字段数据类型 添加删除-字段 约束(主外键默认检查) 查看表结构: 语法:DESRIBE(描述) table_Name; DESC table_Name ...
- Beta冲刺 5
前言 队名:拖鞋旅游队 组长博客:https://www.cnblogs.com/Sulumer/p/10129059.html 作业博客:https://edu.cnblogs.com/campus ...
- css 清楚浮动的几种方式
方法一: 使用clear属性的空元素 <div style="clear:both;"></div> 方法二:使用overflow属性 给浮动的元素容器添加 ...
- Excel 常用属性的一小部分
1.由于工作需要,最近积累了一些Excel中的相关知识,特此记录 Workbooks xlbooks = xlApp.Workbooks; Workbook xlbook = xlbooks.Add( ...
- [亲身实践]linux命令行下配置网路
1.在命令行下输入setup, 2.之后出现下图,选择网络配置 4.配置IP地址,子网掩码,DNS 5.保存之后回到命令行模式下,输入service network restart,至此网络配置完成
- C#中的抽象类、抽象方法和虚方法
[抽象类]abstract 修饰符可与类和方法一起使用定义抽象类的目的是提供可由其子类共享的一般形式.子类可以根据自身需要扩展抽象类.抽象类不能实例化.抽象方法没有函数体.抽象方法必须在子类中给出具体 ...
- AI之旅(5):正则化与牛顿方法
前置知识 导数,矩阵的逆 知识地图 正则化是通过为参数支付代价的方式,降低系统复杂度的方法.牛顿方法是一种适用于逻辑回归的求解方法,相比梯度上升法具有迭代次数少,消耗资源多的特点. 过拟合与欠 ...
- SQLyog 报错2058 :连接 mysql 8.0.11 解决方法
下载新版的 mysql 8.0.11 安装. 为了方便安装查看,我下载了sqlyog 工具 连接 mysql 配置新连接报错:错误号码 2058,分析是 mysql 密码加密方法变了. 解决方法:wi ...
- 转发: 探秘Java中的String、StringBuilder以及StringBuffer
原文地址 探秘Java中String.StringBuilder以及StringBuffer 相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家 ...