diff --git a/conf.json b/conf.json index 383c89db8d0c2dbc19c09d424cba245dfbe4c9ec..2872a9af32bbdc21506692ae9cd92891e109ddd2 100644 --- a/conf.json +++ b/conf.json @@ -8,6 +8,8 @@ "bins":19, "removed_top_bins":3, "pitch_min":0, - "pitch_step":1 + "pitch_step":1, + "height_scale":5, + "width_scale" :0.5 } diff --git a/linescan.py b/linescan.py index 707d0c0a1e9271050f37bf65763bb6c165807276..68e50af5ba0f1438c7702d27e43d7407534f0c09 100755 --- a/linescan.py +++ b/linescan.py @@ -29,6 +29,9 @@ else: camera.exposure_mode='off' camera.shutter_speed=conf["shutter_milliseconds"]*1000 rawCapture = PiRGBArray(camera, size=tuple(conf["resolution"])) + # allow the camera to warmup + print("[INFO] warming up...") + time.sleep(conf["camera_warmup_time"]) # we are a Jack MIDI jack_client to send MIDI messages @@ -44,11 +47,6 @@ def process(frames): midi_outport.write_midi_event(0,midi_output_queue.pop()) jack_client.activate() -# allow the camera to warmup -print("[INFO] warming up...") -time.sleep(conf["camera_warmup_time"]) - -pixel_count=0 histogram_steps=conf["bins"] threshold=conf["threshold"] @@ -70,6 +68,8 @@ while True: # cropped_frame=frame[100:280,0:640] cropped_frame=frame[0:480,0:640] + + # histogram output # crop single line for color histogram output line_frame=cropped_frame[140:141,5:635] # compute b/w histogram @@ -77,11 +77,9 @@ while True: histogram=np.zeros(histogram_steps,dtype=np.uint16) for pixel in np.nditer(line_frame): histogram[(int)(pixel*histogram_steps/256)]+=1 - + # send histogram as MIDI CC messages index=1 - for pixel in np.nditer(histogram[0:-conf['removed_top_bins']]): - velocity=pixel-threshold if velocity>127: velocity=127 @@ -89,12 +87,45 @@ while True: velocity=0 packet=((0xB<<4), index, velocity) # MIDI CC ("Continuous Controller") message midi_output_queue.append(packet) - index+=1 - cv2.imshow("Security Feed", cropped_frame) - #cv2.imshow("Security Feed 2", histogram) + # shape output + # gather depth data from a laser line projection + gray=cv2.cvtColor(cropped_frame, cv2.COLOR_BGR2GRAY) + grad_y = cv2.Sobel(gray, cv2.CV_8U, 0, 2, ksize=5, scale=-.1, delta=0, borderType=cv2.BORDER_DEFAULT) + _, laser = cv2.threshold(grad_y, 165, 255, cv2.THRESH_BINARY) + weights=np.arange(laser.shape[0],dtype=float) + laser[0:400][0:640]=0 + laser[478:480][0:640]=0 + + weighted=np.tensordot(laser,weights,[[0],[0]]) + count =np.sum (laser.astype(float),0) + depths =weighted / count + + depths=depths[count>0] # cut NaN's + + # cut floor (small percentile) + baseline=np.percentile(depths,95) + depths=depths[depths<baseline-2] + + depth_min =np.min(depths) + depth_mean =np.mean(depths) + depth_width =np.sum(depths>0) + depth_height=baseline-depth_mean + + print("baseline "+str(baseline)+" min "+str(depth_min)+" mean "+str(depth_mean)+" width "+str(depth_width)+" height "+str(depth_height)) + + # send out mean width and height of the scanned pieces by MIDI CC 64 and 65. + midi_output_queue.append(((0xB<<4), 64, int(depth_height*conf['height_scale']))) + midi_output_queue.append(((0xB<<4), 65, int(depth_width *conf['width_scale' ]))) + # impaint max to laser image (preview) + laser[int(baseline+1)][:]=100 + laser[int(depth_min)][:]=100 + + cv2.imshow("Security Feed", cropped_frame) + cv2.imshow("laser", laser) + # if the `q` key is pressed, break from the lop key = cv2.waitKey(1) & 0xFF if key == ord("q"):