Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Use different Docker image for blender verification #3844

Merged
merged 8 commits into from
Feb 19, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,43 +1,41 @@
import os
import sys
import pickle
from typing import Dict

import numpy as np
import OpenEXR
from PIL import Image

import decision_tree
from img_format_converter import \
ConvertTGAToPNG, ConvertEXRToPNG
from imgmetrics import \
ImgMetrics
from img_format_converter import ConvertTGAToPNG, ConvertEXRToPNG
from imgmetrics import ImgMetrics

CROP_NAME = "/golem/output/scene_crop.png"
CROP_NAME = "scene_crop.png"
VERIFICATION_SUCCESS = "TRUE"
VERIFICATION_FAIL = "FALSE"
TREE_PATH = "/golem/scripts_verifier/tree35_[crr=87.71][frr=0.92].pkl"

def compare_crop_window(cropped_img_path,
rendered_scene_path,
xres, yres,
output_filename_path='metrics.txt'):

def calculate_metrics(reference_img_path,
result_img_path,
xres,
yres,
metrics_output_filename='metrics.txt'):
"""
This is the entry point for calculation of metrics between the
rendered_scene and the sample(cropped_img) generated for comparison.
:param cropped_img_path:
:param rendered_scene_path:
:param reference_img_path:
:param result_img_path:
:param xres: x position of crop (left, top)
:param yres: y position of crop (left, top)
:param output_filename_path:
:param metrics_output_filename:
:return:
"""

cropped_img, scene_crops, rendered_scene = \
_load_and_prepare_img_for_comparison(
cropped_img_path,
rendered_scene_path,
xres, yres)
_load_and_prepare_images_for_comparison(reference_img_path,
result_img_path,
xres,
yres)

best_crop = None
best_img_metrics = None
Expand All @@ -47,7 +45,7 @@ def compare_crop_window(cropped_img_path,
effective_metrics, classifier, labels, available_metrics = get_metrics()

# First try not offset crop

# TODO this shouldn't depend on the crops' ordering
default_crop = scene_crops[0]
default_metrics = compare_images(cropped_img, default_crop, available_metrics)
try:
Expand All @@ -58,9 +56,9 @@ def compare_crop_window(cropped_img_path,
default_metrics['Label'] = VERIFICATION_FAIL
if default_metrics['Label'] == VERIFICATION_SUCCESS:
default_crop.save(CROP_NAME)
return ImgMetrics(default_metrics).write_to_file(output_filename_path)
return ImgMetrics(default_metrics).write_to_file(metrics_output_filename)
else:
# Try offsete crops
# Try offset crops
for crop in scene_crops[1:]:
try:
img_metrics = compare_images(cropped_img, crop, available_metrics)
Expand All @@ -74,114 +72,88 @@ def compare_crop_window(cropped_img_path,
break
if best_crop and best_img_metrics:
best_crop.save(CROP_NAME)
return ImgMetrics(best_img_metrics).write_to_file(output_filename_path)
return ImgMetrics(best_img_metrics).write_to_file(metrics_output_filename)
else:
# We didnt find any better match in offset crops, return the default one
default_crop.save(CROP_NAME)
path_to_metrics = ImgMetrics(default_metrics).write_to_file(output_filename_path)
path_to_metrics = ImgMetrics(default_metrics).write_to_file(metrics_output_filename)
return path_to_metrics

#This is unexpected but handle in case of errors
# This is unexpected but handle in case of errors
stub_data = {element:-1 for element in get_labels_from_metrics(available_metrics)}
stub_data['Label'] = VERIFICATION_FAIL
path_to_metrics = ImgMetrics(stub_data).write_to_file(output_filename_path)
path_to_metrics = ImgMetrics(stub_data).write_to_file(metrics_output_filename)
return path_to_metrics


def load_classifier():
data = decision_tree.DecisionTree.load(TREE_PATH)

return data[0], data[1]

def classify_with_tree(metrics, classifier, feature_labels):

def classify_with_tree(metrics, classifier, feature_labels):
features = dict()
for label in feature_labels:
features[label] = metrics[label]

results = classifier.classify_with_feature_vector(features, feature_labels)

return results[0].decode('utf-8')

def _load_and_prepare_img_for_comparison(cropped_img_path,
rendered_scene_path,
xres, yres):

def _load_and_prepare_images_for_comparison(reference_img_path,
result_img_path,
xres,
yres):

"""
This function prepares (i.e. crops) the rendered_scene so that it will
fit the sample(cropped_img) generated for comparison.

:param cropped_img_path:
:param rendered_scene_path:
:param reference_img_path:
:param result_img_path:
:param xres: x position of crop (left, top)
:param yres: y position of crop (left, top)
:return:
"""
rendered_scene = None
# if rendered scene has .exr format need to convert it for .png format
if os.path.splitext(rendered_scene_path)[1] == ".exr":
check_input = OpenEXR.InputFile(rendered_scene_path).header()[
'channels']
if 'RenderLayer.Combined.R' in check_input:
sys.exit("There is no support for OpenEXR multilayer")
file_name = "/tmp/scene.png"
ConvertEXRToPNG(rendered_scene_path, file_name)
rendered_scene = Image.open(file_name)
elif os.path.splitext(rendered_scene_path)[1] == ".tga":
file_name = "/tmp/scene.png"
ConvertTGAToPNG(rendered_scene_path, file_name)
rendered_scene = Image.open(file_name)
else:
rendered_scene = Image.open(rendered_scene_path)

cropped_img = Image.open(cropped_img_path)
(crop_width, crop_height) = cropped_img.size

rendered_scene = convert_to_png_if_needed(result_img_path)
reference_img = convert_to_png_if_needed(reference_img_path)
(crop_width, crop_height) = reference_img.size
crops = get_crops(rendered_scene, xres, yres, crop_width, crop_height)
return reference_img, crops, rendered_scene

return cropped_img, crops, rendered_scene


def get_crops(input, x, y, width, height):
crops = []

scene_crop = input.crop((x, y, x + width, y + height))

crops.append(scene_crop)

scene_crop_left = input.crop((x-1, y, x + width-1, y + height))
def get_file_extension_lowercase(file_path):
return os.path.splitext(file_path)[1][1:].lower()

crops.append(scene_crop_left)

scene_crop_left_up = input.crop((x-1, y-1, x + width-1, y + height-1))

crops.append(scene_crop_left_up)

scene_crop_up = input.crop((x, y-1, x + width, y + height-1))

crops.append(scene_crop_up)

scene_crop_up_right = input.crop((x+1, y-1, x + width+1, y + height-1))

crops.append(scene_crop_up_right)

scene_crop_right = input.crop((x+1, y, x + width+1, y + height))

crops.append(scene_crop_right)

scene_crop_down_right = input.crop((x+1, y+1, x + width+1, y + height+1))

crops.append(scene_crop_down_right)

scene_crop_down = input.crop((x, y+1, x + width, y + height+1))

crops.append(scene_crop_down)

scene_crop_down_left = input.crop((x-1, y+1, x + width-1, y + height+1))
def convert_to_png_if_needed(img_path):
extension = get_file_extension_lowercase(img_path)
name = os.path.basename(img_path)
file_name = os.path.join("/tmp/", name)
if extension == "exr":
channels = OpenEXR.InputFile(img_path).header()['channels']
if 'RenderLayer.Combined.R' in channels:
sys.exit("There is no support for OpenEXR multilayer")
ConvertEXRToPNG(img_path, file_name)
elif extension == "tga":
ConvertTGAToPNG(img_path, file_name)
else:
file_name = img_path
return Image.open(file_name)

crops.append(scene_crop_down_left)

def get_crops(rendered_scene, x, y, width, height):
crops = []
offsets = [0, 1, -1]
for x_offset in offsets:
for y_offset in offsets:
crop = rendered_scene.crop((x + x_offset,
y + y_offset,
x + width - x_offset,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this the buggy version? - instead of + ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is.
But fix is waiting in different pull request. And previous version wasn't less buggy probably

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or I can apply this fix in this pull request.
I don't know

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please apply in this PR, there's no point in submitting known buggy code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, done

y + height - y_offset))
crops.append(crop)
return crops


def get_metrics():
classifier, feature_labels = load_classifier()
available_metrics = ImgMetrics.get_metric_classes()
Expand All @@ -193,12 +165,14 @@ def get_metrics():
effective_metrics.append(metric)
return effective_metrics, classifier, feature_labels, available_metrics


def get_labels_from_metrics(metrics):
labels = []
for metric in metrics:
labels.extend(metric.get_lables())
return labels


def compare_images(image_a, image_b, metrics) -> Dict:
"""
This the entry point for calculating metrics between image_a, image_b
Expand Down
6 changes: 3 additions & 3 deletions apps/blender/resources/images/scripts_verifier/verificator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import blender_render as blender
from crop_generator import WORK_DIR, OUTPUT_DIR, SubImage, Region, PixelRegion, \
generate_single_random_crop_data, Crop
from img_metrics_calculator import compare_crop_window
from img_metrics_calculator import calculate_metrics

def get_crop_with_id(id: int, crops: [List[Crop]]) -> Optional[Crop]:
for crop in crops:
Expand Down Expand Up @@ -78,10 +78,10 @@ def make_verdict( subtask_file_paths, crops, results ):

for crop, subtask in zip(crop_data['results'], subtask_file_paths):
crop_path = os.path.join(OUTPUT_DIR, crop)
results_path = compare_crop_window(crop_path,
results_path = calculate_metrics(crop_path,
subtask,
left, top,
output_filename_path=os.path.join(OUTPUT_DIR, crop_data['crop']['outfilebasename'] + "metrics.txt"))
metrics_output_filename=os.path.join(OUTPUT_DIR, crop_data['crop']['outfilebasename'] + "metrics.txt"))

with open(results_path, 'r') as f:
data = json.load(f)
Expand Down