Compare commits

...

3 Commits

Author SHA1 Message Date
Matt McWilliams f103133b9f Almost blew past a good stopping point.
This script can now, on at least one example. locate the largest contours on the page and then put those contours in an array.
It should also look for the largest, most outlying, to prevent errors in the case of large contours in the image.
They should never go past the holes.

Next step: use this for straightening, which will be good for the image extraction script.
Use them as registration points and then just rotate, shift and "shoot" by cropping at a point relative to the holes.

For calibration/templating, look into pattern matching fiducials after getting hole punch coordinates.
2022-11-08 22:47:36 -05:00
Matt McWilliams e5d9d654ac Merge remote-tracking branch 'origin/main' 2022-11-08 21:10:50 -05:00
Matt McWilliams 55cc8ed22c Add a "stipple_random" script that, unlike the sine, uses shuf and a sequence of integers to generate a random number to apply as the "step" in the range of stipple settings 2022-11-04 21:42:39 -04:00
2 changed files with 240 additions and 1 deletions

View File

@ -2,6 +2,34 @@ import sys
import cv2 import cv2
import numpy as np import numpy as np
def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
if width is None and height is None:
return image
if width is None:
r = height / float(h)
dim = (int(w * r), height)
else:
r = width / float(w)
dim = (width, int(h * r))
resized = cv2.resize(image, dim, interpolation = inter)
return resized
def display (image) :
resized = image_resize(image, 800, 800)
cv2.imshow('img', resized)
while True:
key = cv2.waitKey(0)
if key == 27:
cv2.destroyAllWindows()
break
exit(0)
if len(sys.argv) < 2: if len(sys.argv) < 2:
print('Please provide path to image for analysis') print('Please provide path to image for analysis')
exit(1) exit(1)
@ -15,4 +43,66 @@ templateFile = sys.argv[-1]
print(f'Analyzing {scanImage} and creating {templateFile}') print(f'Analyzing {scanImage} and creating {templateFile}')
#https://stackoverflow.com/questions/51456660/opencv-detecting-drilled-holes img = cv2.imread(scanImage)
height, width = img.shape[:2]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray, 31)
ret, thresh = cv2.threshold(blur, 200, 255, cv2.THRESH_BINARY)
canny = cv2.Canny(thresh, 75, 200)
contours, hierarchy = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
contour_list = []
area_list = []
for contour in contours:
approx = cv2.approxPolyDP(contour, 0.01 * cv2.arcLength(contour, True), True)
area = cv2.contourArea(contour)
area_list.append(area)
contour_list.append(contour)
maxArea=0
maxIndex=0
for i in range(len(area_list)) :
area = area_list[i]
if area > maxArea:
maxArea = area
maxIndex = i
count = 0
hole_punches = []
centers = []
centersStr = []
area_range = 0
# pretty good
# add position constraint
while count < 6 :
area_range+=1
for i in range(len(area_list)) :
area = area_list[i]
if area == maxArea or area * ((100 + area_range) / 100) > maxArea :
M = cv2.moments(contour_list[i])
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
strC = f'{cX},{cY}'
if strC in centersStr :
continue
centers.appendStr(strC)
corners.append((cX, cY))
print(f'{cX},{cY}')
cv2.circle(img, (cX, cY), 40, (255, 0, 0), -1)
hole_punches.append(contour_list[i])
count+=1
print(f'Found hole punches within {area_range}% of largest')
cv2.drawContours(img, hole_punches, -1, (0, 255, 0), 20)
display(img)

149
stipple_random.sh Normal file
View File

@ -0,0 +1,149 @@
#!/bin/bash
###########################
#
# Run the stipple_gen script on a sequence
# of PNG images and then render the resulting
# preview images into a video. Fluctuate settings
# via a sine wave.
#
###########################
if [[ "${1}" == "" ]]; then
echo "Please provide a directory of images as the first argument"
exit 1
fi
INPUT=`realpath "${1}"`
OUTPUT=`realpath "${2}"`
CONFIG="${3}"
SINGLE="${4}"
if [ ! -d "${INPUT}" ]; then
echo "Directory ${1} doesn't exist"
exit 2
fi
mkdir -p "${OUTPUT}"
PI=3.14159265359
FPS=24
MULTIPLE=3
STEP=$(echo "scale=6;360/45" | bc -l)
AMP=1.0
STARTANGLE=270
RATE=`echo "scale=0;${FPS}/${MULTIPLE}" | bc`
WIDTH=404
HEIGHT=374
DOTSIZE_MIN=1.8
DOTSIZE_MAX=6
DOTSIZE_HALF=`echo "scale=6;($DOTSIZE_MAX - $DOTSIZE_MIN) / 2" | bc`
DOTSIZE=`echo "scale=6;($DOTSIZE_MIN + $DOTSIZE_HALF)" | bc`
DOTSIZE_MULTIPLE=$DOTSIZE_HALF
PARTICLES_MIN=200
PARTICLES_MAX=1000
PARTICLES_HALF=`echo "($PARTICLES_MAX - $PARTICLES_MIN) / 2" | bc`
PARTICLES=$((PARTICLES_MIN+PARTICLES_HALF))
PARTICLES_MULTIPLE=$PARTICLES_HALF
if [[ "${CONFIG}" == "" ]]; then
echo "Please provide a config file"
exit 1
fi
IMAGES=""
fluctuation () {
i=$1
ANGLE=$(echo "scale=6;$STARTANGLE+($i * $STEP)" | bc)
FLUCTUATION=$(echo "scale=6;s($ANGLE*($PI/180))*$AMP" | bc -l)
echo $FLUCTUATION
}
stipple () {
png="${1}"
frame="${2}"
rand="${3}"
filename=`basename "${png}"`
name=`echo "${filename}" | cut -d'.' -f1`
num=`echo "${name}" | awk -F'_' '{print $(NF)}'`
tmp=`mktemp`.png
fluc=`fluctuation $rand`
particles=`echo "scale=0;($PARTICLES-($fluc*$PARTICLES_MULTIPLE))/1" | bc`
dotsize=`echo "scale=6;$DOTSIZE+($fluc*$DOTSIZE_MULTIPLE)" | bc`
#echo $fluc
echo "maxParticles: $particles"
echo "dotSizeFactor: $dotsize"
bash white.sh "${png}" "${tmp}"
source "${CONFIG}"
cd ~/src/stipple_gen/
bash stipple_gen.sh \
--inputImage "${tmp}" \
--outputImage "${OUTPUT}/${name}_rendered.png" \
--outputSVG "${OUTPUT}/${name}.svg" \
--config "${CONFIG}" \
--dotSizeFactor $dotsize \
--maxParticles $particles
if [[ "${invert}" == "true" ]]; then
convert "${OUTPUT}/${name}_rendered.png" -channel RGB -negate "${OUTPUT}/${name}_rendered.png"
fi
rm "${tmp}"
cd ~/src/animation/
if [ "${MODE}" != "tsp" ]; then
opt=`mktemp`.svg
CURRENT=$(pwd)
cd /
svgsort --no-adjust "${OUTPUT}/${name}.svg" "${opt}"
cd $CURRENT
mv "${opt}" "${OUTPUT}/${name}.svg"
fi
}
random_int () {
shuf -i 1-360 -n 1
}
if [[ "${SINGLE}" != "" ]]; then
echo "Rendering a single frame, #${SINGLE}"
#files in dir
for png in "${INPUT}/"*.png ; do
if [[ ${i} -eq ${SINGLE} ]]; then
r=$(random_int)
#echo $r
stipple "${png}" ${i} ${r}
break
fi
i=$((i+1))
done
exit
fi
i=0;
#files in dir
for png in "${INPUT}/"*.png ; do
r=$(random_int)
#echo $r
stipple "${png}" ${i} ${r}
i=$((i+1))
done
if [[ "${IMAGES}" == "" ]]; then
part=`echo "${name}" | awk -F'_0' '{print $1}'`
IMAGES="${OUTPUT}/${part}_%06d_rendered.png"
VIDEO="${OUTPUT}/${part}.mov"
fi
ffmpeg -y -r ${RATE} -f image2 -i "${IMAGES}" \
-r ${FPS} \
-c:v prores_ks -profile:v 3 \
"${VIDEO}"