Advertisement
UF6

HoughCircles

UF6
Jan 13th, 2025 (edited)
10
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.56 KB | Source Code | 0 0
  1. import cv2
  2. import numpy as np
  3. from fpdf import FPDF
  4. from pptx import Presentation
  5. from pptx.util import Inches
  6. import matplotlib.pyplot as plt
  7.  
  8. # Load the image
  9. image_path = "C:/Users/HAL 9000/Downloads/image2.jpg"
  10. image = cv2.imread(image_path)
  11.  
  12. # Convert to grayscale
  13. gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  14.  
  15. # Thresholding to create a binary image (air vs particles)
  16. _, binary_image = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
  17.  
  18. # Detect circular particles using HoughCircles
  19. circles = cv2.HoughCircles(binary_image, cv2.HOUGH_GRADIENT, dp=1, minDist=20, param1=50, param2=30, minRadius=10, maxRadius=100)
  20.  
  21. # If circles are found, convert them to integers
  22. if circles is not None:
  23.     circles = np.round(circles[0, :]).astype("int")
  24.  
  25. # Function to detect non-circular particles (based on contour area and perimeter)
  26. def detect_non_circular_particles(binary_image):
  27.     contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  28.     non_circular_particles = []
  29.  
  30.     for contour in contours:
  31.         # Approximate the contour to a polygon and compute its aspect ratio
  32.         epsilon = 0.02 * cv2.arcLength(contour, True)
  33.         approx = cv2.approxPolyDP(contour, epsilon, True)
  34.        
  35.         # Calculate the aspect ratio (width/height) of the bounding box
  36.         x, y, w, h = cv2.boundingRect(approx)
  37.         aspect_ratio = w / float(h) if h != 0 else 0
  38.         # A non-circular particle will have an aspect ratio different from 1
  39.         if aspect_ratio > 1.5 or aspect_ratio < 0.5:
  40.             non_circular_particles.append(contour)
  41.    
  42.     return non_circular_particles
  43.  
  44. # Detect non-circular particles
  45. non_circular_particles = detect_non_circular_particles(binary_image)
  46.  
  47. # Calculate the statistics for circular particles
  48. circular_diameters = []
  49. if circles is not None:
  50.     for circle in circles:
  51.         radius = circle[2]
  52.         circular_diameters.append(2 * radius)
  53.  
  54. # Statistics for circular particles
  55. circular_particles_count = len(circular_diameters)
  56. average_diameter = np.mean(circular_diameters) if circular_particles_count > 0 else 0
  57. std_dev_diameter = np.std(circular_diameters) if circular_particles_count > 0 else 0
  58.  
  59. # Area of circular and non-circular particles
  60. circular_area = np.pi * (np.array(circular_diameters) / 2) ** 2
  61. non_circular_area = sum([cv2.contourArea(cnt) for cnt in non_circular_particles])
  62.  
  63. # Area ratio
  64. total_area = circular_area.sum() + non_circular_area
  65. area_ratio_circular = circular_area.sum() / total_area
  66. area_ratio_non_circular = non_circular_area / total_area
  67.  
  68. # Saving the segmented images for report purposes
  69. # Save an image with circular particles marked
  70. image_with_circles = image.copy()
  71. if circles is not None:
  72.     for circle in circles:
  73.         cv2.circle(image_with_circles, (circle[0], circle[1]), circle[2], (0, 255, 0), 4)
  74.  
  75. cv2.imwrite("C:/Users/HAL 9000/Downloads/circular_particles.png", image_with_circles)
  76.  
  77. # Save an image with non-circular particles marked
  78. image_with_non_circular = image.copy()
  79. cv2.drawContours(image_with_non_circular, non_circular_particles, -1, (0, 0, 255), 2)
  80. cv2.imwrite("C:/Users/HAL 9000/Downloads/non_circular_particles.png", image_with_non_circular)
  81.  
  82. # --- PDF Generation ---
  83. pdf = FPDF()
  84. pdf.add_page()
  85.  
  86. # Add title
  87. pdf.set_font('Arial', 'B', 16)
  88. pdf.cell(200, 10, txt="Particle Analysis Report", ln=True, align='C')
  89.  
  90. # Add statistics for circular particles
  91. pdf.ln(10)
  92. pdf.set_font('Arial', '', 12)
  93. pdf.cell(200, 10, txt=f"Number of Circular Particles: {circular_particles_count}")
  94. pdf.ln(10)
  95. pdf.cell(200, 10, txt=f"Average Diameter of Circular Particles: {average_diameter:.2f} units")
  96. pdf.ln(10)
  97. pdf.cell(200, 10, txt=f"Standard Deviation of Diameters: {std_dev_diameter:.2f} units")
  98. pdf.ln(10)
  99.  
  100. # Add Area Ratio
  101. pdf.cell(200, 10, txt=f"Area Ratio (Circular Particles): {area_ratio_circular:.2f}")
  102. pdf.ln(10)
  103. pdf.cell(200, 10, txt=f"Area Ratio (Non-Circular Particles): {area_ratio_non_circular:.2f}")
  104. pdf.ln(10)
  105.  
  106. # Add images to the PDF
  107. pdf.image("C:/Users/HAL 9000/Downloads/circular_particles.png", x=10, y=60, w=90)
  108. pdf.image("C:/Users/HAL 9000/Downloads/non_circular_particles.png", x=110, y=60, w=90)
  109.  
  110. # Save the PDF
  111. output_pdf = "C:/Users/HAL 9000/Downloads/particle_analysis_report.pdf"
  112. pdf.output(output_pdf)
  113.  
  114. print(f"PDF report generated and saved to {output_pdf}")
  115.  
  116. #Generate PPTX presentation with slides for each segment
  117. presentation = Presentation()
  118.  
  119. # Circular particles slide
  120. slide = presentation.slides.add_slide(presentation.slide_layouts[5])
  121. slide.shapes.title.text = "Circular Particles"
  122. slide.shapes.add_picture("C:/Users/HAL 9000/Downloads/circular_particles.png", Inches(1), Inches(1.5), Inches(6), Inches(4.5))
  123. textbox = slide.shapes.add_textbox(Inches(1), Inches(6), Inches(6), Inches(1))
  124. textbox.text = f"Number of Circular Particles: {circular_particles_count}\nAverage Diameter: {average_diameter:.2f} units"
  125.  
  126. # Non-Circular particles slide
  127. slide = presentation.slides.add_slide(presentation.slide_layouts[5])
  128. slide.shapes.title.text = "Non-Circular Particles"
  129. slide.shapes.add_picture("C:/Users/HAL 9000/Downloads/non_circular_particles.png", Inches(1), Inches(1.5), Inches(6), Inches(4.5))
  130. textbox = slide.shapes.add_textbox(Inches(1), Inches(6), Inches(6), Inches(1))
  131. textbox.text = f"Area Ratio (Circular): {area_ratio_circular:.2f}\nArea Ratio (Non-Circular): {area_ratio_non_circular:.2f}"
  132.  
  133. #Save the PPTX
  134. pptx_path = "C:/Users/HAL 9000/Downloads/particle_analysis_report.pptx"
  135. presentation.save(pptx_path)
  136.  
  137. print(f"PPTX report generated and saved to {pptx_path}")
  138.  
  139. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement