2021-09-24

OpenCV ANN_MLP

下面是用來測試 tcl-opencv 新加入的 ANN_MLP command,寫了一個簡單的測試程式來測試:

package require opencv

proc showImage {image columns name} {
    set bigImage [cv::Mat::Mat 0 0 $::cv::CV_32F]

    for {set i 0} {$i < [$image rows]} {incr i} {
        set row [$image rowRange $i [expr $i + 1]]
        set rs  [$row reshape 0 $columns]
        $bigImage push_back $rs

        $row close
        $rs close
    }

    set bigImageT [$bigImage transpose]
    ::cv::imshow $name $bigImageT

    $bigImageT close
    $bigImage close
}

#
# Download file from:
# https://github.com/opencv/opencv/tree/master/samples/data/data01.xml
#
set filename "data01.xml"

set f [::cv::FileStorage]
$f open $filename $::cv::FileStorage::READ
set dataMat [$f readMat datamat]
set labelsMat [$f readMat labelsmat]
$f close

set data [$dataMat convert $::cv::CV_32F]
set labels [$labelsMat convert $::cv::CV_32F]
puts "Loading training data... read [$data rows] rows of data"

$dataMat close
$labelsMat close

set data_train [cv::Mat::Mat 0 0 $::cv::CV_32F]
set data_test  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_train  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_test   [cv::Mat::Mat 0 0 $::cv::CV_32F]

for {set i 0} {$i < [$data rows]} {incr i} {
    if {[expr $i%2]==0} {
         $data_train push_back [$data rowRange $i [expr $i + 1]]
         $labels_train push_back [$labels rowRange $i [expr $i + 1]]
    } else {
         $data_test push_back [$data rowRange $i [expr $i + 1]]
         $labels_test push_back [$labels rowRange $i [expr $i + 1]]
    }
}

$data close
$labels close

# MLP does not support categorical variables by explicitly.
# Update our labels
set res_train [::cv::Mat::zeros [$labels_train rows] 2 $::cv::CV_32F]
for {set i 0} {$i < [$labels_train rows]} {incr i} {
    set value [expr int([$labels_train at [list $i 0] 0])]
    $res_train at [list $i $value] 0 1
}

set res_test [::cv::Mat::zeros [$labels_test rows] 2 $::cv::CV_32F]
for {set i 0} {$i < [$labels_test rows]} {incr i} {
    set value [expr int([$labels_test at [list $i 0] 0])]
    $res_test at [list $i $value] 0 1
}

showImage $data_train 28 "train data"
showImage $data_test 28 "test data"
cv::waitKey 0

set term [::cv::TermCriteria [expr $::cv::EPS | $::cv::COUNT] 500 0.0001]

set layers [::cv::Mat::Mat 1 3 $::cv::CV_32S]
$layers at [list 0 0] 0 [$data_train cols]
$layers at [list 0 1] 0 10
$layers at [list 0 2] 0 [$res_train cols]

set mlp [::cv::ml::ANN_MLP]
$mlp setLayerSizes $layers
$mlp setActivationFunction $::cv::ml::MLP_SIGMOID_SYM 0 0
$mlp setTrainMethod $::cv::ml::MLP_BACKPROP 0.0001 0
$mlp setTermCriteria $term

puts "Training..."
set trainData [::cv::ml::TrainData $data_train $::cv::ml::ROW_SAMPLE $res_train]
$mlp train $trainData 
$trainData close
$data_train close
$labels_train close
$res_train close
$term close
$layers close

$mlp save "mlp.xml"
$mlp close

set mlp [::cv::ml::ANN_MLP::load "mlp.xml"]

#
# MLP will give us a vector of "probabilities" at the prediction stage
#
puts "Predicting..."
set response [$mlp predict $data_test]
set res [lindex $response 1]

puts ""
puts "Labels test: "
set labels_test2 [$labels_test convert $::cv::CV_32S]
for {set i 0} {$i < [$labels_test2 rows]} {incr i} {
    puts -nonewline "[$labels_test2 at [list $i 0] 0] "
}

puts ""
set correct 0
for {set i 0} {$i < [$labels_test2 rows]} {incr i} {
    set row [$res rowRange $i [expr $i + 1]]
    set rowt [$row transpose]
    set rvalue [cv::minMaxIdx $rowt]
    set max [lindex $rvalue 1]
    set maxidx [lindex $max 1]
  
    $row close
    $rowt close
    puts -nonewline "$maxidx "
    if {$maxidx==[$labels_test2 at [list $i 0] 0]} {
        incr correct
    }
}
puts ""
puts "accuracy: [expr 100 * $correct/[$labels_test rows]]"

$res close
$data_test close
$labels_test close
$labels_test2 close
$res_test close

OpenCV RTrees

下面是用來測試 tcl-opencv 新加入的 RTrees command,寫了一個簡單的測試程式來測試:

package require opencv

proc showImage {image columns name} {
    set bigImage [cv::Mat::Mat 0 0 $::cv::CV_32F]

    for {set i 0} {$i < [$image rows]} {incr i} {
        set row [$image rowRange $i [expr $i + 1]]
        set rs  [$row reshape 0 $columns]
        $bigImage push_back $rs

        $row close
        $rs close
    }

    set bigImageT [$bigImage transpose]
    ::cv::imshow $name $bigImageT

    $bigImageT close
    $bigImage close
}

#
# Download file from:
# https://github.com/opencv/opencv/tree/master/samples/data/data01.xml
#
set filename "data01.xml"

set f [::cv::FileStorage]
$f open $filename $::cv::FileStorage::READ
set dataMat [$f readMat datamat]
set labelsMat [$f readMat labelsmat]
$f close

set data [$dataMat convert $::cv::CV_32F]
set labels [$labelsMat convert $::cv::CV_32S]
puts "Loading training data... read [$data rows] rows of data"

$dataMat close
$labelsMat close

set data_train [cv::Mat::Mat 0 0 $::cv::CV_32F]
set data_test  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_train  [cv::Mat::Mat 0 0 $::cv::CV_32S]
set labels_test   [cv::Mat::Mat 0 0 $::cv::CV_32S]

for {set i 0} {$i < [$data rows]} {incr i} {
    if {[expr $i%2]==0} {
         $data_train push_back [$data rowRange $i [expr $i + 1]]
         $labels_train push_back [$labels rowRange $i [expr $i + 1]]
    } else {
         $data_test push_back [$data rowRange $i [expr $i + 1]]
         $labels_test push_back [$labels rowRange $i [expr $i + 1]]
    }
}

$data close
$labels close

showImage $data_train 28 "train data"
showImage $data_test 28 "test data"
cv::waitKey 0

set term [::cv::TermCriteria [expr $::cv::EPS | $::cv::COUNT] 5000 0.00000001]

set rt [::cv::ml::RTrees]
$rt setMaxCategories 2
# It is necessary to setup max
$rt setMaxDepth 20
$rt setMinSampleCount 1
$rt setTruncatePrunedTree 1
$rt setUse1SERule 1
$rt setUseSurrogates 0
$rt setCVFolds 1
$rt setCalculateVarImportance 1
$rt setTermCriteria $term

puts "Training..."
set trainData [::cv::ml::TrainData $data_train $::cv::ml::ROW_SAMPLE $labels_train]
$rt train $trainData
$trainData close
$data_train close
$labels_train close
$term close

$rt save "rt.xml"
$rt close

set rt [::cv::ml::RTrees::load "rt.xml"]

puts "Predicting..."
set response [$rt predict $data_test]
set res [lindex $response 1]

puts ""
puts "Labels test: "
for {set i 0} {$i < [$labels_test rows]} {incr i} {
    puts -nonewline "[$labels_test at [list $i 0] 0] "
}
puts ""
puts "Response: "
set res2 [$res convert $::cv::CV_32S]
for {set i 0} {$i < [$res2 rows]} {incr i} {
    puts -nonewline "[$res2 at [list $i 0] 0] "
}

puts ""
set correct 0
for {set i 0} {$i < [$labels_test rows]} {incr i} {
    if {[$res2 at [list $i 0] 0]==[$labels_test at [list $i 0] 0]} {
        incr correct
    }
}
puts "accuracy: [expr 100 * $correct/[$labels_test rows]]"

$res close
$res2 close
$data_test close
$labels_test close

2021-09-23

OpenCV Boost

下面是用來測試 tcl-opencv 新加入的 Boost command,寫了一個簡單的測試程式來測試:

package require opencv

proc showImage {image columns name} {
    set bigImage [cv::Mat::Mat 0 0 $::cv::CV_32F]

    for {set i 0} {$i < [$image rows]} {incr i} {
        set row [$image rowRange $i [expr $i + 1]]
        set rs  [$row reshape 0 $columns]
        $bigImage push_back $rs

        $row close
        $rs close
    }

    set bigImageT [$bigImage transpose]
    ::cv::imshow $name $bigImageT

    $bigImageT close
    $bigImage close
}

#
# Download file from:
# https://github.com/opencv/opencv/tree/master/samples/data/data01.xml
#
set filename "data01.xml"

set f [::cv::FileStorage]
$f open $filename $::cv::FileStorage::READ
set dataMat [$f readMat datamat]
set labelsMat [$f readMat labelsmat]
$f close

set data [$dataMat convert $::cv::CV_32F]
set labels [$labelsMat convert $::cv::CV_32S]
puts "Loading training data... read [$data rows] rows of data"

$dataMat close
$labelsMat close

set data_train [cv::Mat::Mat 0 0 $::cv::CV_32F]
set data_test  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_train  [cv::Mat::Mat 0 0 $::cv::CV_32S]
set labels_test   [cv::Mat::Mat 0 0 $::cv::CV_32S]

for {set i 0} {$i < [$data rows]} {incr i} {
    if {[expr $i%2]==0} {
         $data_train push_back [$data rowRange $i [expr $i + 1]]
         $labels_train push_back [$labels rowRange $i [expr $i + 1]]
    } else {
         $data_test push_back [$data rowRange $i [expr $i + 1]]
         $labels_test push_back [$labels rowRange $i [expr $i + 1]]
    }
}

$data close
$labels close

showImage $data_train 28 "train data"
showImage $data_test 28 "test data"
cv::waitKey 0

set boost [::cv::ml::Boost]
# It is necessary to setup max
$boost setMaxDepth 10
$boost setUseSurrogates 0
$boost setBoostType $::cv::ml::BOOST_REAL
$boost setWeakCount 100
$boost setWeightTrimRate 0.95

puts "Training..."
set trainData [::cv::ml::TrainData $data_train $::cv::ml::ROW_SAMPLE $labels_train]
$boost train $trainData
$trainData close
$data_train close
$labels_train close

$boost save "boost.xml"
$boost close

set boost [::cv::ml::Boost::load "boost.xml"]

puts "Predicting..."
set response [$boost predict $data_test]
set res [lindex $response 1]

$boost close

puts ""
puts "Labels test: "
for {set i 0} {$i < [$labels_test rows]} {incr i} {
    puts -nonewline "[$labels_test at [list $i 0] 0] "
}
puts ""
puts "Response: "
set res2 [$res convert $::cv::CV_32S]
for {set i 0} {$i < [$res2 rows]} {incr i} {
    puts -nonewline "[$res2 at [list $i 0] 0] "
}

puts ""
set correct 0
for {set i 0} {$i < [$labels_test rows]} {incr i} {
    if {[$res2 at [list $i 0] 0]==[$labels_test at [list $i 0] 0]} {
        incr correct
    }
}
puts "accuracy: [expr 100 * $correct/[$labels_test rows]]"

$res close
$res2 close
$data_test close
$labels_test close

OpenCV DTrees

下面是用來測試 tcl-opencv 新加入的 DTrees command,寫了一個簡單的測試程式來測試:

package require opencv

proc showImage {image columns name} {
    set bigImage [cv::Mat::Mat 0 0 $::cv::CV_32F]

    for {set i 0} {$i < [$image rows]} {incr i} {
        set row [$image rowRange $i [expr $i + 1]]
        set rs  [$row reshape 0 $columns]
        $bigImage push_back $rs

        $row close
        $rs close
    }

    set bigImageT [$bigImage transpose]
    ::cv::imshow $name $bigImageT

    $bigImageT close
    $bigImage close
}

#
# Download file from:
# https://github.com/opencv/opencv/tree/master/samples/data/data01.xml
#
set filename "data01.xml"

set f [::cv::FileStorage]
$f open $filename $::cv::FileStorage::READ
set dataMat [$f readMat datamat]
set labelsMat [$f readMat labelsmat]
$f close

set data [$dataMat convert $::cv::CV_32F]
set labels [$labelsMat convert $::cv::CV_32S]
puts "Loading training data... read [$data rows] rows of data"

$dataMat close
$labelsMat close

set data_train [cv::Mat::Mat 0 0 $::cv::CV_32F]
set data_test  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_train  [cv::Mat::Mat 0 0 $::cv::CV_32S]
set labels_test   [cv::Mat::Mat 0 0 $::cv::CV_32S]

for {set i 0} {$i < [$data rows]} {incr i} {
    if {[expr $i%2]==0} {
         $data_train push_back [$data rowRange $i [expr $i + 1]]
         $labels_train push_back [$labels rowRange $i [expr $i + 1]]
    } else {
         $data_test push_back [$data rowRange $i [expr $i + 1]]
         $labels_test push_back [$labels rowRange $i [expr $i + 1]]
    }
}

$data close
$labels close

showImage $data_train 28 "train data"
showImage $data_test 28 "test data"
cv::waitKey 0

set dt [::cv::ml::DTrees]
$dt setMaxCategories 2
# It is necessary to setup max
$dt setMaxDepth 20
$dt setMinSampleCount 1
$dt setTruncatePrunedTree 1
$dt setUse1SERule 1
$dt setUseSurrogates 0
$dt setCVFolds 1

puts "Training..."
set trainData [::cv::ml::TrainData $data_train $::cv::ml::ROW_SAMPLE $labels_train]
$dt train $trainData
$trainData close
$data_train close
$labels_train close

$dt save "dt.xml"

puts "Predicting..."
set response [$dt predict $data_test]
set res [lindex $response 1]

$dt close

puts ""
puts "Labels test: "
for {set i 0} {$i < [$labels_test rows]} {incr i} {
    puts -nonewline "[$labels_test at [list $i 0] 0] "
}
puts ""
puts "Response: "
set res2 [$res convert $::cv::CV_32S]
for {set i 0} {$i < [$res2 rows]} {incr i} {
    puts -nonewline "[$res2 at [list $i 0] 0] "
}

puts ""
set correct 0
for {set i 0} {$i < [$labels_test rows]} {incr i} {
    if {[$res2 at [list $i 0] 0]==[$labels_test at [list $i 0] 0]} {
        incr correct
    }
}
puts "accuracy: [expr 100 * $correct/[$labels_test rows]]"

$res close
$res2 close
$data_test close
$labels_test close

2021-09-22

OpenCV SVMSGD

下面是用來測試 tcl-opencv 新加入的  SVMSGD command,寫了一個簡單的測試程式來測試:

package require opencv

proc showImage {image columns name} {
    set bigImage [cv::Mat::Mat 0 0 $::cv::CV_32F]

    for {set i 0} {$i < [$image rows]} {incr i} {
        set row [$image rowRange $i [expr $i + 1]]
        set rs  [$row reshape 0 $columns]
        $bigImage push_back $rs

        $row close
        $rs close
    }
    
    set bigImageT [$bigImage transpose]
    ::cv::imshow $name $bigImageT

    $bigImageT close
    $bigImage close
}

#
# Download file from:
# https://github.com/opencv/opencv/tree/master/samples/data/data01.xml
#

set filename "data01.xml"

set f [::cv::FileStorage]
$f open $filename $::cv::FileStorage::READ
set dataMat [$f readMat datamat]
set labelsMat [$f readMat labelsmat]
$f close

# Notice: SVMSGD label type is CV_32F
set data [$dataMat convert $::cv::CV_32F]
set labels [$labelsMat convert $::cv::CV_32F]
puts "Loading training data... read [$data rows] rows of data"

$dataMat close
$labelsMat close

set data_train [cv::Mat::Mat 0 0 $::cv::CV_32F]
set data_test  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_train  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_test   [cv::Mat::Mat 0 0 $::cv::CV_32F]

for {set i 0} {$i < [$data rows]} {incr i} {
    if {[expr $i%2]==0} {
         $data_train push_back [$data rowRange $i [expr $i + 1]]
         $labels_train push_back [$labels rowRange $i [expr $i + 1]]
    } else {
         $data_test push_back [$data rowRange $i [expr $i + 1]]
         $labels_test push_back [$labels rowRange $i [expr $i + 1]]
    }
}

$data close
$labels close

# SVMSGD labels is -1 and 1, so update our labels
for {set i 0} {$i < [$labels_train rows]} {incr i} {
    if {[$labels_train at [list $i 0] 0]==0} {
        $labels_train at [list $i 0] 0 -1.0
    }
    puts [$labels_train at [list $i 0] 0]
}

for {set i 0} {$i < [$labels_test rows]} {incr i} {
    if {[$labels_test at [list $i 0] 0]==0} {
        $labels_test at [list $i 0] 0 -1.0
    }
}

showImage $data_train 28 "train data"
showImage $data_test 28 "test data"
cv::waitKey 0

set term [::cv::TermCriteria [expr $::cv::EPS | $::cv::COUNT] 1000 0.001]

set svmsgd [::cv::ml::SVMSGD]
$svmsgd setSvmsgdType $::cv::ml::SVMSGD_ASGD
$svmsgd setMarginType $::cv::ml::SVMSGD_HARD_MARGIN
$svmsgd setMarginRegularization 0.00001
$svmsgd setInitialStepSize 0.05
$svmsgd setStepDecreasingPower 0.75
$svmsgd setTermCriteria $term

puts "Training..."
set trainData [::cv::ml::TrainData $data_train $::cv::ml::ROW_SAMPLE $labels_train]
$svmsgd train $trainData
$trainData close
$data_train close
$labels_train close
$term close

$svmsgd save "svmsgd.xml"

puts "Predicting..."
set response [$svmsgd predict $data_test]
set res [lindex $response 1]

$svmsgd close

puts ""
puts "Labels test: "
for {set i 0} {$i < [$labels_test rows]} {incr i} {
    puts -nonewline "[$labels_test at [list $i 0] 0] "
}
puts ""
puts "Response: [$res size]"
for {set i 0} {$i < [$res rows]} {incr i} {
    puts -nonewline "[$res at [list $i 0] 0] "
}

puts ""
set correct 0
for {set i 0} {$i < [$labels_test rows]} {incr i} {
    if {[$res at [list $i 0] 0]==[$labels_test at [list $i 0] 0]} {
        incr correct
    }
}
puts "accuracy: [expr 100 * $correct/[$labels_test rows]]"

$res close
$data_test close
$labels_test close

OpenCV LogisticRegression

OpenCV 也在 ML module 提供了 Logistic Regression。

下面是用來測試 tcl-opencv 新加入的  LogisticRegression command,寫了一個簡單的測試程式來測試:

package require opencv

proc showImage {image columns name} {
    set bigImage [cv::Mat::Mat 0 0 $::cv::CV_32F]

    for {set i 0} {$i < [$image rows]} {incr i} {
        set row [$image rowRange $i [expr $i + 1]]
        set rs  [$row reshape 0 $columns]
        $bigImage push_back $rs

        $row close
        $rs close
    }
    
    set bigImageT [$bigImage transpose]
    ::cv::imshow $name $bigImageT

    $bigImageT close
    $bigImage close
}

#
# Download file from:
# https://github.com/opencv/opencv/tree/master/samples/data/data01.xml
#
set filename "data01.xml"

set f [::cv::FileStorage]
$f open $filename $::cv::FileStorage::READ
set dataMat [$f readMat datamat]
set labelsMat [$f readMat labelsmat]
$f close

# Notice: LogisticRegression label type is CV_32F
set data [$dataMat convert $::cv::CV_32F]
set labels [$labelsMat convert $::cv::CV_32F]
puts "Loading training data... read [$data rows] rows of data"

$dataMat close
$labelsMat close

set data_train [cv::Mat::Mat 0 0 $::cv::CV_32F]
set data_test  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_train  [cv::Mat::Mat 0 0 $::cv::CV_32F]
set labels_test   [cv::Mat::Mat 0 0 $::cv::CV_32F]

for {set i 0} {$i < [$data rows]} {incr i} {
    if {[expr $i%2]==0} {
         $data_train push_back [$data rowRange $i [expr $i + 1]]
         $labels_train push_back [$labels rowRange $i [expr $i + 1]]
    } else {
         $data_test push_back [$data rowRange $i [expr $i + 1]]
         $labels_test push_back [$labels rowRange $i [expr $i + 1]]
    }
}

$data close
$labels close

showImage $data_train 28 "train data"
showImage $data_test 28 "test data"
cv::waitKey 0

set logi [::cv::ml::LogisticRegression]
$logi setLearningRate 0.001
$logi setIterations 10
$logi setRegularization $::cv::ml::LOGISTIC_REG_L2
$logi setTrainMethod $::cv::ml::LOGISTIC_BATCH
$logi setMiniBatchSize 1

puts "Training..."
set trainData [::cv::ml::TrainData $data_train $::cv::ml::ROW_SAMPLE $labels_train]
$logi train $trainData
$trainData close
$data_train close
$labels_train close

$logi save "logi.xml"

puts "Predicting..."
set response [$logi predict $data_test]
set res [lindex $response 1]

$logi close

puts ""
puts "Labels test: "
set labels_test2 [$labels_test convert $::cv::CV_32S]
for {set i 0} {$i < [$labels_test2 rows]} {incr i} {
    puts -nonewline "[$labels_test2 at [list $i 0] 0] "
}
puts ""
puts "Response: "
for {set i 0} {$i < [$res rows]} {incr i} {
    puts -nonewline "[$res at [list $i 0] 0] "
}

puts ""
set correct 0
for {set i 0} {$i < [$labels_test2 rows]} {incr i} {
    if {[$res at [list $i 0] 0]==[$labels_test2 at [list $i 0] 0]} {
        incr correct
    }
}
puts "accuracy: [expr 100 * $correct/[$labels_test2 rows]]"

$res close
$data_test close
$labels_test close
$labels_test2 close

2021-09-18

OpenCV kmeans

k-means clustering (維基百科)


我的問題是要怎麼確認我新加到 tcl-opencv 的 kmeans command 是不是有加正確,所以寫了一個簡單的測試程式來測試:

package require opencv

set k [expr 1 + int(5 * rand())]
set samplecount [expr 500 + int(500 * rand())]

set colors [list [list 255 0 0 0] [list 0 0 255 0] \
                 [list 0 255 0 0] [list 0 165 255 0] \
                 [list 255 165 0 0] [list 255 255 255 0]]

set image [::cv::Mat::Mat 512 512 $::cv::CV_8UC3]
set term [::cv::TermCriteria [expr $::cv::EPS | $::cv::COUNT] 10 1]

while {1} {
    $image setTo [list 0 0 0 0]
    set points [cv::Mat::Mat $samplecount 1 $::cv::CV_32FC2]
    cv::randu $points [list 0 0 0 0] [list 512 512 0 0]

    set result [cv::kmeans $points $k None $term 3 $::cv::KMEANS_PP_CENTERS]
    puts "K = $k, compactness: [lindex $result 0]"

    set labels [lindex $result 1]
    for {set i 0} {$i < [$points rows]} {incr i} {
        set x [expr int([$points at [list $i 0] 0])]
        set y [expr int([$points at [list $i 0] 1])]

        set color [lindex $colors [expr int([$labels at [list $i 0] 0])]]
        cv::circle $image $x $y 2 $color 1 $cv::LINE_AA 0
    }

    set output [lindex $result 2]
    for {set i 0} {$i < [$output rows]} {incr i} {
        set x [expr int([$output at [list $i 0] 0])]
        set y [expr int([$output at [list $i 1] 0])]
        set color [lindex $colors $i]
        cv::circle $image $x $y 40 $color 1 $cv::LINE_AA 0
    }

    ::cv::imshow "Result" $image

    $labels close
    $points close
    
    set key [::cv::waitKey 0]
    if {$key==[scan "q" %c] || $key == 27} {
        break
    } else {
        set k [expr 2 + int(3 * rand())]
        set samplecount [expr 200 + int(1000 * rand())]
    }
}

$image close
$term close

2021-09-14

Tclunqlite v0.3.7

 Tclunqlite

這是一個小更新的版本,將 UnQLite 的 source code 更新到最新的版本,所以將版本升為 v0.3.7。

2021-09-01

tcl-opencv: Tcl extension for OpenCV library

tcl-opencv

 

在使用 C++ 寫 OpenCV 小程式的時候,我突然間對怎麼實作一個  Tcl extension for OpenCV library 有了想法,所以花時間寫出來一個驗證想法。現在我把成品放到 Github 上。