mirror of
https://github.com/ruby-opencv/ruby-opencv
synced 2023-03-27 23:22:12 -04:00
Example for contour retrieval modes
This commit is contained in:
parent
3b52f0b223
commit
b2d3b26944
3 changed files with 139 additions and 0 deletions
Binary file not shown.
Before Width: | Height: | Size: 269 KiB After Width: | Height: | Size: 3.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 1.7 KiB |
139
examples/contours/contour_retrieval_modes.rb
Executable file
139
examples/contours/contour_retrieval_modes.rb
Executable file
|
@ -0,0 +1,139 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# This file shows the different retrieval modes for contour detection
|
||||
#
|
||||
require "opencv"
|
||||
|
||||
# Load image
|
||||
# The structure of the image is "explained" in bitmap-contours-with-labels.png
|
||||
cvmat = OpenCV::CvMat.load("bitmap-contours.png")
|
||||
|
||||
# "find_contours" does only operate on bitmap images (black/white)
|
||||
mat = OpenCV::CvMat.new(cvmat.rows, cvmat.cols, :cv8u, 1)
|
||||
(cvmat.rows * cvmat.cols).times do |i|
|
||||
mat[i] = (cvmat[i][0] <= 128) ? OpenCV::CvScalar.new(0) : OpenCV::CvScalar.new(255)
|
||||
end
|
||||
|
||||
# find_contours takes two parameters:
|
||||
# 1. Retrieval mode (:mode, defines the structure of the contour sequence returned)
|
||||
# - CV_RETR_LIST (default)
|
||||
# - CV_RETR_EXTERNAL
|
||||
# - CV_RETR_CCOMP
|
||||
# - CV_RETR_TREE
|
||||
# 2. Retrieval Method (:method, how the contours are approximated)
|
||||
# - CV_CHAIN_CODE
|
||||
# - CV_CHAIN_APPROX_NONE
|
||||
# - CV_CHAIN_APPROX_SIMPLE (default)
|
||||
# - CV_CHAIN_APPROX_TC89_L1
|
||||
# - CV_CHAIN_APPROX_T89_KCOS
|
||||
# - CV_LINK_RUNS
|
||||
|
||||
#
|
||||
# The default: CV_RETR_LIST and CV_CHAIN_APPROX_SIMPLE
|
||||
# This produces a flat list of contours that can be traversed with .h_next and .h_prev
|
||||
#
|
||||
puts "Detecting using CV_RETR_LIST and CV_CHAIN_APPROX_SIMPLE"
|
||||
contour = mat.find_contours(:mode => OpenCV::CV_RETR_LIST, :method => OpenCV::CV_CHAIN_APPROX_SIMPLE)
|
||||
cindex=1
|
||||
|
||||
while contour
|
||||
puts "Contour ##{cindex} is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour = contour.h_next
|
||||
cindex+=1
|
||||
end
|
||||
|
||||
#
|
||||
# CV_RETR_EXTERNAL retrieves only the outer most non "hole" contour
|
||||
#
|
||||
puts '-'*80
|
||||
puts "Detecting using CV_RETR_EXTERNAL and CV_CHAIN_APPROX_SIMPLE"
|
||||
contour = mat.find_contours(:mode => OpenCV::CV_RETR_EXTERNAL, :method => OpenCV::CV_CHAIN_APPROX_SIMPLE)
|
||||
cindex=1
|
||||
|
||||
while contour
|
||||
puts "Contour ##{cindex} is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour = contour.h_next
|
||||
cindex+=1
|
||||
end
|
||||
|
||||
#
|
||||
# CV_RETR_CCOMP organizes the contours in a two level deep stack
|
||||
# The first level holds the contours
|
||||
# The second level contains the holes of the contours in level 1
|
||||
#
|
||||
# C00001 <-> C00000 <-> C000 <-> C0
|
||||
# | |
|
||||
# V V
|
||||
# H0000 H00
|
||||
#
|
||||
puts '-'*80
|
||||
puts "Detecting using CV_RETR_CCOMP and CV_CHAIN_APPROX_SIMPLE"
|
||||
contour = mat.find_contours(:mode => OpenCV::CV_RETR_CCOMP, :method => OpenCV::CV_CHAIN_APPROX_SIMPLE)
|
||||
|
||||
# C00001
|
||||
puts "Contour #1 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour = contour.h_next
|
||||
|
||||
# C00000
|
||||
puts "Contour #2 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour = contour.h_next
|
||||
|
||||
# C000
|
||||
puts "Contour #3 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour_down = contour.v_next
|
||||
|
||||
# H0000
|
||||
puts "Contour #4 is #{contour_down.contour_area} px^2 (width: #{contour_down.bounding_rect.width}, height: #{contour_down.bounding_rect.height}, type: #{(contour_down.hole?)?"hole":"contour"})"
|
||||
contour = contour.h_next
|
||||
|
||||
# C0
|
||||
puts "Contour #5 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour_down = contour.v_next
|
||||
|
||||
# H00
|
||||
puts "Contour #6 is #{contour_down.contour_area} px^2 (width: #{contour_down.bounding_rect.width}, height: #{contour_down.bounding_rect.height}, type: #{(contour_down.hole?)?"hole":"contour"})"
|
||||
|
||||
#
|
||||
# CV_RETR_TREE manages the contours in a tree structure
|
||||
# This reconstructs the complete hierarchy of contours and holes that the image displayed
|
||||
#
|
||||
# C0
|
||||
# |
|
||||
# V
|
||||
# H00
|
||||
# |
|
||||
# V
|
||||
# C000
|
||||
# |
|
||||
# V
|
||||
# H0000-------+
|
||||
# | |
|
||||
# V V
|
||||
# C00000 C00001
|
||||
#
|
||||
puts '-'*80
|
||||
puts "Detecting using CV_RETR_TREE and CV_CHAIN_APPROX_SIMPLE"
|
||||
contour = mat.find_contours(:mode => OpenCV::CV_RETR_TREE, :method => OpenCV::CV_CHAIN_APPROX_SIMPLE)
|
||||
|
||||
# C0
|
||||
puts "Contour #1 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour = contour.v_next
|
||||
|
||||
# H00
|
||||
puts "Contour #2 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour = contour.v_next
|
||||
|
||||
# C000
|
||||
puts "Contour #3 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour = contour.v_next
|
||||
|
||||
# H0000
|
||||
puts "Contour #4 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour = contour.v_next
|
||||
|
||||
# C00000
|
||||
puts "Contour #5 is #{contour.contour_area} px^2 (width: #{contour.bounding_rect.width}, height: #{contour.bounding_rect.height}, type: #{(contour.hole?)?"hole":"contour"})"
|
||||
contour_right = contour.h_next
|
||||
|
||||
# C00001
|
||||
puts "Contour #6 is #{contour_right.contour_area} px^2 (width: #{contour_right.bounding_rect.width}, height: #{contour_right.bounding_rect.height}, type: #{(contour_right.hole?)?"hole":"contour"})"
|
Loading…
Add table
Reference in a new issue