I’m trying to inference image with upscaling model in flutter. but output image is not as expected.
Its seems problem in normalize or in output to image.
Orginal Image: https://i.sstatic.net/AJX5gj48.png
Output Image: https://i.sstatic.net/A2u3ahd8.png
Model Shape:
<code>Model input shape: ['batch_size', 3, 'width', 'height']
Model output shape: ['batch_size', 3, 'width', 'height']
</code>
<code>Model input shape: ['batch_size', 3, 'width', 'height']
Model output shape: ['batch_size', 3, 'width', 'height']
</code>
Model input shape: ['batch_size', 3, 'width', 'height']
Model output shape: ['batch_size', 3, 'width', 'height']
Logs:
<code>flutter: Is normalized: true
flutter: Image normalized successfully.
flutter: Input tensor created successfully.
flutter: Width: 1428, Height: 804, Channel: 3
</code>
<code>flutter: Is normalized: true
flutter: Image normalized successfully.
flutter: Input tensor created successfully.
flutter: Width: 1428, Height: 804, Channel: 3
</code>
flutter: Is normalized: true
flutter: Image normalized successfully.
flutter: Input tensor created successfully.
flutter: Width: 1428, Height: 804, Channel: 3
I tried this code and out of scope now.
<code> Future<void> inference() async {
if (selectedImage == null) {
debugPrint('No image selected');
return;
}
if (selectedImage != null) {
Float32List? floatData;
try {
img.Image normalizedImage =
img.normalize(selectedImage!, min: 0, max: 255);
Uint8List imageData = normalizedImage.getBytes(order: img.ChannelOrder.rgb);
floatData = Float32List.fromList(
imageData.map((byte) => byte / 255.0).toList());
debugPrint("Is normalized: ${isNormalized(floatData)}");
} catch (e) {
debugPrint("Error during normalization: $e");
}
final shape = [1, 3, selectedImage!.width, selectedImage!.height];
debugPrint('Image normalized successfully.');
final inputOrt =
OrtValueTensor.createTensorWithDataList(floatData!, shape);
final inputs = {'input': inputOrt};
debugPrint('Input tensor created successfully.');
final runOptions = OrtRunOptions();
final outputs = await ortSession.runAsync(runOptions, inputs);
inputOrt.release();
runOptions.release();
outputs?.forEach((element) {
final outputValue = element?.value;
if (outputValue is List<List<List<List<double>>>>) {
img.Image generatedImage = generateImageFromOutput(outputValue);
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
child: SizedBox(
width: generatedImage.width.toDouble(),
height: generatedImage.height.toDouble(),
child: Image.memory(
Uint8List.fromList(img.encodePng(generatedImage)),
fit: BoxFit.contain,
),
),
);
},
);
} else {
debugPrint("Output is of unknown type");
}
element?.release();
});
}
}
img.Image generateImageFromOutput(
List<List<List<List<double>>>> outputValue) {
int width = outputValue[0][0].length;
int height = outputValue[0][0][0].length;
int channel = outputValue[0].length;
print("Width: $width, Height: $height, Channel: $channel");
// Create the image
img.Image generatedImage = img.Image(width: width, height: height);
// Set pixel values
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// Extract RGB values from the output tensor data
int r = (outputValue[0][0][x][y] * 255).toInt().clamp(0, 255);
int g = (outputValue[0][1][x][y] * 255).toInt().clamp(0, 255);
int b = (outputValue[0][2][x][y] * 255).toInt().clamp(0, 255);
// Set pixel value in the generated image
generatedImage.setPixelRgb(x, y, r, g, b);
}
}
return generatedImage;
}
</code>
<code> Future<void> inference() async {
if (selectedImage == null) {
debugPrint('No image selected');
return;
}
if (selectedImage != null) {
Float32List? floatData;
try {
img.Image normalizedImage =
img.normalize(selectedImage!, min: 0, max: 255);
Uint8List imageData = normalizedImage.getBytes(order: img.ChannelOrder.rgb);
floatData = Float32List.fromList(
imageData.map((byte) => byte / 255.0).toList());
debugPrint("Is normalized: ${isNormalized(floatData)}");
} catch (e) {
debugPrint("Error during normalization: $e");
}
final shape = [1, 3, selectedImage!.width, selectedImage!.height];
debugPrint('Image normalized successfully.');
final inputOrt =
OrtValueTensor.createTensorWithDataList(floatData!, shape);
final inputs = {'input': inputOrt};
debugPrint('Input tensor created successfully.');
final runOptions = OrtRunOptions();
final outputs = await ortSession.runAsync(runOptions, inputs);
inputOrt.release();
runOptions.release();
outputs?.forEach((element) {
final outputValue = element?.value;
if (outputValue is List<List<List<List<double>>>>) {
img.Image generatedImage = generateImageFromOutput(outputValue);
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
child: SizedBox(
width: generatedImage.width.toDouble(),
height: generatedImage.height.toDouble(),
child: Image.memory(
Uint8List.fromList(img.encodePng(generatedImage)),
fit: BoxFit.contain,
),
),
);
},
);
} else {
debugPrint("Output is of unknown type");
}
element?.release();
});
}
}
img.Image generateImageFromOutput(
List<List<List<List<double>>>> outputValue) {
int width = outputValue[0][0].length;
int height = outputValue[0][0][0].length;
int channel = outputValue[0].length;
print("Width: $width, Height: $height, Channel: $channel");
// Create the image
img.Image generatedImage = img.Image(width: width, height: height);
// Set pixel values
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// Extract RGB values from the output tensor data
int r = (outputValue[0][0][x][y] * 255).toInt().clamp(0, 255);
int g = (outputValue[0][1][x][y] * 255).toInt().clamp(0, 255);
int b = (outputValue[0][2][x][y] * 255).toInt().clamp(0, 255);
// Set pixel value in the generated image
generatedImage.setPixelRgb(x, y, r, g, b);
}
}
return generatedImage;
}
</code>
Future<void> inference() async {
if (selectedImage == null) {
debugPrint('No image selected');
return;
}
if (selectedImage != null) {
Float32List? floatData;
try {
img.Image normalizedImage =
img.normalize(selectedImage!, min: 0, max: 255);
Uint8List imageData = normalizedImage.getBytes(order: img.ChannelOrder.rgb);
floatData = Float32List.fromList(
imageData.map((byte) => byte / 255.0).toList());
debugPrint("Is normalized: ${isNormalized(floatData)}");
} catch (e) {
debugPrint("Error during normalization: $e");
}
final shape = [1, 3, selectedImage!.width, selectedImage!.height];
debugPrint('Image normalized successfully.');
final inputOrt =
OrtValueTensor.createTensorWithDataList(floatData!, shape);
final inputs = {'input': inputOrt};
debugPrint('Input tensor created successfully.');
final runOptions = OrtRunOptions();
final outputs = await ortSession.runAsync(runOptions, inputs);
inputOrt.release();
runOptions.release();
outputs?.forEach((element) {
final outputValue = element?.value;
if (outputValue is List<List<List<List<double>>>>) {
img.Image generatedImage = generateImageFromOutput(outputValue);
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
child: SizedBox(
width: generatedImage.width.toDouble(),
height: generatedImage.height.toDouble(),
child: Image.memory(
Uint8List.fromList(img.encodePng(generatedImage)),
fit: BoxFit.contain,
),
),
);
},
);
} else {
debugPrint("Output is of unknown type");
}
element?.release();
});
}
}
img.Image generateImageFromOutput(
List<List<List<List<double>>>> outputValue) {
int width = outputValue[0][0].length;
int height = outputValue[0][0][0].length;
int channel = outputValue[0].length;
print("Width: $width, Height: $height, Channel: $channel");
// Create the image
img.Image generatedImage = img.Image(width: width, height: height);
// Set pixel values
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// Extract RGB values from the output tensor data
int r = (outputValue[0][0][x][y] * 255).toInt().clamp(0, 255);
int g = (outputValue[0][1][x][y] * 255).toInt().clamp(0, 255);
int b = (outputValue[0][2][x][y] * 255).toInt().clamp(0, 255);
// Set pixel value in the generated image
generatedImage.setPixelRgb(x, y, r, g, b);
}
}
return generatedImage;
}