зеркало из https://github.com/microsoft/landcover.git
Two big changes:
- Fixed everything about new label class counting - Fully converted corrections into point corrections
This commit is contained in:
Родитель
c59f18064a
Коммит
e898a4a990
|
@ -181,7 +181,7 @@ def record_correction():
|
|||
SESSION_HANDLER.get_session(bottle.request.session.id).add_entry(data) # record this interaction
|
||||
|
||||
#
|
||||
lat, lon = data["point"]["x"], data["point"]["y"]
|
||||
lon, lat = data["point"]["x"], data["point"]["y"]
|
||||
class_list = data["classes"]
|
||||
name_list = [item["name"] for item in class_list]
|
||||
color_list = [item["color"] for item in class_list]
|
||||
|
@ -191,11 +191,11 @@ def record_correction():
|
|||
# load the current predicted patches crs and transform
|
||||
data_crs, data_transform = SESSION_HANDLER.get_session(bottle.request.session.id).current_transform
|
||||
|
||||
x, y = fiona.transform.transform(origin_crs, data_crs.to_dict(), [lon], [lat])
|
||||
x, y = fiona.transform.transform(origin_crs, data_crs.to_string(), [lon], [lat])
|
||||
x = x[0]
|
||||
y = y[0]
|
||||
|
||||
dst_row, dst_col = (~data_transform) * (y, x)
|
||||
dst_col, dst_row = (~data_transform) * (x,y)
|
||||
dst_row = int(np.floor(dst_row))
|
||||
dst_col = int(np.floor(dst_col))
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ def _load_model(model):
|
|||
return False
|
||||
return {
|
||||
"fn": model["model"]["fn"],
|
||||
"type": model["model"]["type"],
|
||||
"fine_tune_layer": model["model"]["fineTuneLayer"]
|
||||
}
|
||||
|
||||
|
|
|
@ -178,8 +178,11 @@ class KerasDenseFineTune(BackendModel):
|
|||
return output
|
||||
|
||||
def retrain(self, **kwargs):
|
||||
x_train = np.concatenate(self.augment_x_train, axis=0)
|
||||
y_train = np.concatenate(self.augment_y_train, axis=0)
|
||||
x_train = np.array(self.augment_x_train)
|
||||
y_train = np.array(self.augment_y_train)
|
||||
|
||||
print(x_train.shape)
|
||||
print(y_train.shape)
|
||||
|
||||
vals, counts = np.unique(y_train, return_counts=True)
|
||||
|
||||
|
@ -197,12 +200,9 @@ class KerasDenseFineTune(BackendModel):
|
|||
|
||||
return success, message
|
||||
|
||||
def add_sample(self, tdst_row, bdst_row, tdst_col, bdst_col, class_idx):
|
||||
x_features = self.current_features[tdst_row:bdst_row+1, tdst_col:bdst_col+1, :].copy().reshape(-1, self.current_features.shape[2])
|
||||
y_samples = np.zeros((x_features.shape[0]), dtype=np.uint8)
|
||||
y_samples[:] = class_idx
|
||||
self.augment_x_train.append(x_features)
|
||||
self.augment_y_train.append(y_samples)
|
||||
def add_sample_point(self, row, col, class_idx):
|
||||
self.augment_x_train.append(self.current_features[row, col, :].copy())
|
||||
self.augment_y_train.append(class_idx)
|
||||
self.undo_stack.append("sample")
|
||||
|
||||
def undo(self):
|
||||
|
|
|
@ -39,9 +39,7 @@ class TorchFineTuning(BackendModel):
|
|||
|
||||
def __init__(self, model_fn, gpuid, fine_tune_layer):
|
||||
self.model_fn = model_fn
|
||||
self.device = torch.device("cuda:1" if torch.cuda.is_available() else "cpu")
|
||||
|
||||
print("Using device", self.device)
|
||||
self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
||||
|
||||
self.output_channels = 14
|
||||
self.output_features = 64
|
||||
|
|
|
@ -59,24 +59,7 @@
|
|||
|
||||
<h3 style="text-align: center; margin-top:20px;">Correction type:</h3>
|
||||
<div style="padding-left:20px">
|
||||
<div id="classList">
|
||||
<!-- <div class="radio">
|
||||
<button class="circle jscolor" data-class-name="Water" data-jscolor="{valueElement:null,value:'0000FF',position:'left',zIndex:2001,closable:true,closeText:'Close',onFineChange:'updateClassColor(this)'}"></button>
|
||||
<label class="selected"><input type="radio" name="radClasses" class="radNewClass" value="Water" checked><span class="className">Water</span> (<span class="classCounts">0</span> samples since last retrain)</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<button class="circle jscolor" data-class-name="Tree Canopy" data-jscolor="{valueElement:null,value:'008000',position:'left',zIndex:2001,closable:true,closeText:'Close',onFineChange:'updateClassColor(this)'}"></button>
|
||||
<label><input type="radio" name="radClasses" class="radNewClass" value="Tree Canopy"><span class="className">Tree Canopy</span> (<span class="classCounts">0</span> samples since last retrain)</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<button class="circle jscolor" data-class-name="Field" data-jscolor="{valueElement:null,value:'80FF80',position:'left',zIndex:2001,closable:true,closeText:'Close',onFineChange:'updateClassColor(this)'}"></button>
|
||||
<label><input type="radio" name="radClasses" class="radNewClass" value="Field"><span class="className">Field</span> (<span class="classCounts">0</span> samples since last retrain)</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<button class="circle jscolor" data-class-name="Built" data-jscolor="{valueElement:null,value:'806060',position:'left',zIndex:2001,closable:true,closeText:'Close',onFineChange:'updateClassColor(this)'}"></button>
|
||||
<label><input type="radio" name="radClasses" class="radNewClass" value="Built"><span class="className">Built</span> (<span class="classCounts">0</span> samples since last retrain)</label>
|
||||
</div> -->
|
||||
</div>
|
||||
<div id="classList"></div>
|
||||
<div style="text-align: center; margin-top:10px; margin-bottom:20px;">
|
||||
<button id="btnNewClass" style="background-color: gray; border-color: white;"> Add new class</button>
|
||||
</div>
|
||||
|
@ -220,18 +203,20 @@
|
|||
for(var i=0;i<MODELS[gCurrentModel]["classes"].length;i++){
|
||||
var currentClass = MODELS[gCurrentModel]["classes"][i];
|
||||
|
||||
console.debug(currentClass)
|
||||
|
||||
var newClassIdx = CLASSES.length + 1;
|
||||
var newClassIdx = CLASSES.length;
|
||||
var newClassName = currentClass["name"];
|
||||
var newColor = currentClass["color"];
|
||||
|
||||
var newClassElement = $("<div class='radio'>");
|
||||
var newLabel = $("<label><input type='radio' name='radClasses' class='radNewClass' value='Class "+newClassIdx+"'><span class='className'>"+currentClass["label"]+"</span> (<span class='classCounts'>0</span> samples since last retrain)<i class='fa fa-edit ml-1 classNameEdit'></i></label>");
|
||||
var newLabel = $(" \
|
||||
<label><input type='radio' name='radClasses' class='radClasses' value='"+newClassName+"'><span class='className'>"+newClassName+"</span> (<span class='classCounts'>0</span> samples since last retrain)<i class='fa fa-edit ml-1 classNameEdit'></i></label> \
|
||||
");
|
||||
|
||||
var newPicker = document.createElement('button');
|
||||
newPicker.classList.add("circle");
|
||||
newPicker.classList.add("jscolor");
|
||||
newPicker.setAttribute("data-class-name", "Class "+newClassIdx);
|
||||
newPicker.setAttribute("data-class-label", newClassName);
|
||||
newPicker.setAttribute("data-class-idx", newClassIdx);
|
||||
var output = new jscolor(newPicker, {
|
||||
valueElement: null,
|
||||
value: newColor.substr(1),
|
||||
|
@ -248,7 +233,7 @@
|
|||
$("#classList").append(newClassElement);
|
||||
|
||||
CLASSES.push({
|
||||
"name": "Class " + newClassIdx,
|
||||
"name": newClassName,
|
||||
"color": newColor,
|
||||
"count": 0
|
||||
});
|
||||
|
@ -306,7 +291,7 @@
|
|||
//----------------------------------------------------------------------
|
||||
addCustomLogoControl();
|
||||
addZoomControls();
|
||||
addDrawControls();
|
||||
//addDrawControls();
|
||||
var basemapPickerControl = addBasemapPickerControl(gBasemaps);
|
||||
var basemapPickerControlContainer = basemapPickerControl.getContainer();
|
||||
|
||||
|
@ -381,15 +366,19 @@
|
|||
$("#btnNewClass").click(function(){
|
||||
|
||||
var newClassIdx = CLASSES.length;
|
||||
var newClassName = "Class " + (newClassIdx + 1);
|
||||
var newColor = getRandomColor();
|
||||
|
||||
var newClassElement = $("<div class='radio'>");
|
||||
var newLabel = $("<label><input type='radio' name='radClasses' class='radNewClass' value='Class "+newClassIdx+"'><span class='className'>Class "+newClassIdx+"</span> (<span class='classCounts'>0</span> samples since last retrain)<i class='fa fa-edit ml-1 classNameEdit'></i></label>");
|
||||
var newLabel = $(" \
|
||||
<label><input type='radio' name='radClasses' class='radClasses' value='"+newClassName+"'><span class='className'>"+newClassName+"</span> (<span class='classCounts'>0</span> samples since last retrain)<i class='fa fa-edit ml-1 classNameEdit'></i></label> \
|
||||
");
|
||||
|
||||
var newPicker = document.createElement('button');
|
||||
newPicker.classList.add("circle");
|
||||
newPicker.classList.add("jscolor");
|
||||
newPicker.setAttribute("data-class-name", "Class "+newClassIdx);
|
||||
newPicker.setAttribute("data-class-label", newClassName);
|
||||
newPicker.setAttribute("data-class-idx", newClassIdx);
|
||||
var output = new jscolor(newPicker, {
|
||||
valueElement: null,
|
||||
value: newColor.substr(1),
|
||||
|
@ -406,37 +395,34 @@
|
|||
$("#classList").append(newClassElement);
|
||||
|
||||
CLASSES.push({
|
||||
"name": "Class " + newClassIdx,
|
||||
"name": newClassName,
|
||||
"color": newColor,
|
||||
"count": 0
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Setup radio button change detection
|
||||
//----------------------------------------------------------------------
|
||||
$(document).on('change', '.radNewClass', function(){
|
||||
$(document).on('change', '.radClasses', function(){
|
||||
|
||||
$('.radio label').removeClass("selected");
|
||||
$(this).parent().addClass("selected");
|
||||
|
||||
gSelectedClassIdx = findClassByName(this.value);
|
||||
console.debug(this.value + " " + gSelectedClassIdx);
|
||||
});
|
||||
|
||||
$(document).on('click', '.classNameEdit', function(){
|
||||
var oldName = $(this).siblings(".className").html();
|
||||
var newName = prompt("New label name for '"+oldName+"'");
|
||||
$(this).siblings(".className").html(newName);
|
||||
$(this).siblings(".radNewClass").val(newName);
|
||||
$(this).siblings(".radClasses").val(newName);
|
||||
|
||||
$(this).parent().siblings(".jscolor").attr("data-class-name", newName);
|
||||
|
||||
var classIdx = findClassByName(oldName)
|
||||
var classIdx = findClassByName(oldName);
|
||||
console.debug(classIdx);
|
||||
CLASSES[classIdx]["name"] = newName;
|
||||
|
||||
|
||||
});
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -8,7 +8,7 @@ var addInferenceMouseHandlers = function(){
|
|||
if(!gShiftKeyDown){
|
||||
curSelPoly = getPolyAround(e.latlng, 1, false);
|
||||
}else{
|
||||
curSelPoly = getPolyAround(e.latlng, INFERENCE_WINDOW_SIZE, true);
|
||||
curSelPoly = getPolyAround(e.latlng, INFERENCE_WINDOW_SIZE, true, true);
|
||||
}
|
||||
|
||||
if(gSelectionBox === null){
|
||||
|
@ -35,7 +35,7 @@ var addInferenceMouseHandlers = function(){
|
|||
var curSelPoly = null;
|
||||
if(gShiftKeyDown){
|
||||
// Run the inference path
|
||||
curSelPoly = getPolyAround(e.latlng, INFERENCE_WINDOW_SIZE, true);
|
||||
curSelPoly = getPolyAround(e.latlng, INFERENCE_WINDOW_SIZE, true, true);
|
||||
if(gCurrentSelection === null){ // This condition creates the red selection box on the first click
|
||||
gCurrentSelection = L.polygon(curSelPoly, {
|
||||
color: "#ff0000",
|
||||
|
|
|
@ -12,12 +12,11 @@ var findClassByIdx = function(idx){
|
|||
}
|
||||
|
||||
var renderClassCount = function(name, count){
|
||||
$(".radNewClass[value='"+name+"']").siblings(".classCounts").html(count);
|
||||
$(".radClasses[value='"+name+"']").siblings(".classCounts").html(count);
|
||||
}
|
||||
|
||||
var updateClassColor = function(obj){
|
||||
var className = $(obj.targetElement).attr("data-class-name");
|
||||
var classIdx = findClassByName(className);
|
||||
var classIdx = $(obj.targetElement).attr("data-class-idx");
|
||||
CLASSES[classIdx]["color"] = '#' + obj;
|
||||
};
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
"fn": "data/models/sentinel_demo_model.h5"
|
||||
},
|
||||
"classes":[
|
||||
{"label": "Water", "color": "#0000FF"},
|
||||
{"label": "Tree Canopy", "color": "#008000"},
|
||||
{"label": "Field", "color": "#80FF80"},
|
||||
{"label": "Built", "color": "#806060"}
|
||||
{"name": "Water", "color": "#0000FF"},
|
||||
{"name": "Tree Canopy", "color": "#008000"},
|
||||
{"name": "Field", "color": "#80FF80"},
|
||||
{"name": "Built", "color": "#806060"}
|
||||
]
|
||||
},
|
||||
|
||||
|
@ -30,10 +30,10 @@
|
|||
"fn": "data/models/naip_demo_model.h5"
|
||||
},
|
||||
"classes":[
|
||||
{"label": "Water", "color": "#0000FF"},
|
||||
{"label": "Tree Canopy", "color": "#008000"},
|
||||
{"label": "Field", "color": "#80FF80"},
|
||||
{"label": "Built", "color": "#806060"}
|
||||
{"name": "Water", "color": "#0000FF"},
|
||||
{"name": "Tree Canopy", "color": "#008000"},
|
||||
{"name": "Field", "color": "#80FF80"},
|
||||
{"name": "Built", "color": "#806060"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче