File size: 4,928 Bytes
9d703ce |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
import io
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image, ImageDraw, ImageFont
def draw_findings_on_image(image, findings):
"""
Add annotations to X-ray image based on findings
Args:
image (PIL.Image): Original X-ray image
findings (dict): Analysis findings with probabilities
Returns:
PIL.Image: Annotated image
"""
# Create a copy of the image to draw on
img = image.copy()
draw = ImageDraw.Draw(img)
# Get image dimensions
width, height = img.size
# Try to use a nice font, fall back to default if not available
try:
font = ImageFont.truetype("arial.ttf", 20)
small_font = ImageFont.truetype("arial.ttf", 16)
except IOError:
font = ImageFont.load_default()
small_font = ImageFont.load_default()
# Add findings at the top
y_position = 10
for finding, probability in findings.items():
if isinstance(probability, float):
text = f"{finding}: {probability:.2f}"
# Color code based on probability and finding type
if finding == "No findings":
color = (0, 128, 0) # Green for no findings
elif probability > 0.5:
color = (255, 0, 0) # Red for high probability issues
else:
color = (255, 165, 0) # Orange for lower probability issues
draw.text((10, y_position), text, fill=color, font=small_font)
y_position += 25
return img
def create_combined_visualization(image, image_results, text_results, combined_results):
"""
Create a comprehensive visualization of all analysis results
Args:
image (PIL.Image): Original X-ray image
image_results (dict): Image analysis results
text_results (dict): Text analysis results
combined_results (dict): Combined multimodal results
Returns:
PIL.Image: Visualization image
"""
# Create a copy of the image to draw on
img = image.copy()
# Create a header with the recommendation
recommendation = combined_results.get("Recommendation", "No recommendation")
confidence = combined_results.get("Confidence", "N/A")
# Create a white background for the header
header_height = 60
header_img = Image.new("RGB", (img.width, header_height), color=(255, 255, 255))
header_draw = ImageDraw.Draw(header_img)
# Try to use a nice font, fall back to default if not available
try:
font = ImageFont.truetype("arial.ttf", 18)
small_font = ImageFont.truetype("arial.ttf", 14)
except IOError:
font = ImageFont.load_default()
small_font = ImageFont.load_default()
# Add recommendation text
header_draw.text((10, 5), recommendation, fill=(0, 0, 0), font=font)
header_draw.text(
(10, 35), f"Confidence: {confidence}", fill=(100, 100, 100), font=small_font
)
# Combine the header and image
combined_img = Image.new("RGB", (img.width, img.height + header_height))
combined_img.paste(header_img, (0, 0))
combined_img.paste(img, (0, header_height))
return combined_img
def generate_report_plot(image_findings, text_findings):
"""
Generate a comparison plot of image and text findings
Args:
image_findings (dict): Image analysis results
text_findings (dict): Text analysis results
Returns:
bytes: PNG image data as bytes
"""
# Create figure
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# Plot image findings
image_labels = []
image_values = []
for k, v in image_findings.items():
if isinstance(v, float):
image_labels.append(k)
image_values.append(v)
# Sort by value for better visualization
sorted_indices = np.argsort(image_values)[::-1] # Descending order
image_labels = [image_labels[i] for i in sorted_indices]
image_values = [image_values[i] for i in sorted_indices]
# Plot bars for image findings
ax1.barh(image_labels, image_values, color="skyblue")
ax1.set_xlim(0, 1)
ax1.set_title("X-ray Analysis")
ax1.set_xlabel("Probability")
# Plot text findings (assuming text_findings has a structure to visualize)
ax2.axis("off") # Turn off axis
ax2.text(0.1, 0.9, "Text Analysis Results:", fontweight="bold")
y_pos = 0.8
for key, value in text_findings.items():
if key != "Entities":
ax2.text(0.1, y_pos, f"{key}: {value}")
y_pos -= 0.1
# Adjust layout
plt.tight_layout()
# Convert to image bytes
buf = io.BytesIO()
plt.savefig(buf, format="png")
buf.seek(0)
# Close the plot to avoid memory leaks
plt.close(fig)
return buf.getvalue()
|