Local RSS feed added, new (TV) emblem, diverse ...
parent
f82618e623
commit
7e982884a3
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title type="text">Silly news</title><subtitle type="html">Fake news distribution</subtitle>
|
||||
<updated>2020-05-12T11:13:00+02:00</updated>
|
||||
<id>file://FakeNews.xml</id>
|
||||
<author>
|
||||
<name>wlast</name><uri>https://fakenews.ru</uri>
|
||||
</author>
|
||||
|
||||
<link rel="self" type="application/atom+xml" href="file://FakeNews.xml"/>
|
||||
<link rel="alternate" type="text/html" href="file://FakeNews.xml"/>
|
||||
<rights>Copyright (c) 2020 by fakenews Corp.</rights>
|
||||
|
||||
<entry>
|
||||
<title type="text">Disclaimer: This IS fake news (says a cretan).</title>
|
||||
<id>file://FakeNews.xml/3</id>
|
||||
<updated>2020-05-11T13:16:00+02:00</updated>
|
||||
<published>2020-05-11T13:16:00+02:00</published>
|
||||
<link href="file://FakeNews.xml"/>
|
||||
<summary type="html">This is message #3</summary>
|
||||
|
||||
</entry>
|
||||
<entry>
|
||||
<title type="text">National Enquirer: hacKNology may be part of deep state.</title>
|
||||
<id>file://FakeNews.xml/2</id>
|
||||
<updated>2020-05-12T06:55:00+02:00</updated>
|
||||
<published>2020-05-12T06:55:00+02:00</published>
|
||||
<link href="file://FakeNews.xml"/>
|
||||
<summary type="html">This is message #2</summary>
|
||||
|
||||
</entry>
|
||||
<entry>
|
||||
<title type="text">Reptiloids warn: hacKNology seeks world domination!</title>
|
||||
<id>file://FakeNews.xml/1</id>
|
||||
<updated>2020-05-12T11:13:00+02:00</updated>
|
||||
<published>2020-05-12T11:13:00+02:00</published>
|
||||
<link href="file://FakeNews.xml"/>
|
||||
<summary type="html">This is message #1</summary>
|
||||
|
||||
</entry>
|
||||
|
||||
</feed>
|
12
README.md
12
README.md
|
@ -3,16 +3,20 @@
|
|||
The actual description can be found at
|
||||
https://www.hacknology.de/projekt/2020/pimpedwebcam/
|
||||
|
||||
The emblem.png can be retrieved from
|
||||
https://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png
|
||||
(Take this one for now, I will add an original later ...)
|
||||
|
||||
As there has been confusion about the correct config.ini for akvcam,
|
||||
|
||||
I added a functioning one (store as /etc/akvcam/config.ini - w/ root rights!).
|
||||
|
||||
Also: You will need a 3rd gen. Intel i7/equivalent or better ...
|
||||
|
||||
12.05.20 New/improved features
|
||||
|
||||
Local RSS 'fake news' fun added
|
||||
A more appropriate '3D' logo created
|
||||
Background removal improved (a little bit)
|
||||
More script parameters ...
|
||||
Annoying 'empty room' start screen dropped
|
||||
|
||||
|
||||
11.05.20 New/improved features
|
||||
|
||||
|
|
BIN
emblem.png
BIN
emblem.png
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 15 KiB |
56
funcam.py
56
funcam.py
|
@ -11,6 +11,7 @@ History:
|
|||
06.05.20/KQ Release version
|
||||
09.05.20/KQ Message translation, exception handling, arg passing improved, more general emblem.png
|
||||
09.05.20/KQ Background removal ('green screen'), beta & thus really ugly ...
|
||||
12.05.20/KQ Round kernels shall improve green screen (a little bit), local file rss feed provided
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
|
@ -20,7 +21,7 @@ import datetime, time
|
|||
import cv2
|
||||
import feedparser # To install: Activate (cv) environment, then 'pip3 install feedparser'
|
||||
|
||||
print("<<< funcam started ... >>>",file=sys.stderr)
|
||||
print("\n<<< funcam started ... >>>",file=sys.stderr)
|
||||
# Hint: print() to stderr (fh#2) as the actual video stream goes to stdout (fh#1)!
|
||||
|
||||
print("OpenCV version : "+str(cv2.__version__),file=sys.stderr) # For control purposes
|
||||
|
@ -48,8 +49,9 @@ else:
|
|||
alternate_background = None
|
||||
|
||||
# Prepare scroll line message as an RSS feed. Currently, this is only read once upon start ...
|
||||
''' # Example of an actual RSS feed
|
||||
# Example of an actual RSS feed
|
||||
d = feedparser.parse(rssfeed)
|
||||
print("Feed entries: " + str(len(d.entries)),file=sys.stderr)
|
||||
dt0 = datetime.datetime.strptime(d.entries[2].published, '%Y-%m-%dT%H:%M:%S+02:00').strftime('%H:%M')
|
||||
sRSS0 = dt0 + " " + d.entries[2].title + " +++ "
|
||||
dt1 = datetime.datetime.strptime(d.entries[1].published, '%Y-%m-%dT%H:%M:%S+02:00').strftime('%H:%M')
|
||||
|
@ -58,12 +60,6 @@ dt2 = datetime.datetime.strptime(d.entries[0].published, '%Y-%m-%dT%H:%M:%S+02:0
|
|||
sRSS2 = dt2 + " " + d.entries[0].title + " +++ "
|
||||
msg = "+++ " + sRSS0 + sRSS1 + sRSS2
|
||||
msg = msg.translate(str.maketrans({"ä":"ae", "ö":"oe", "ü":"ue", "ß":"ss", "Ä":"Ae", "Ö":"Oe", "Ü":"Ue"}))
|
||||
'''
|
||||
# Alternate reality ...
|
||||
msg = "+++ Reptiloids warn: hacKNology seeks world domination! "\
|
||||
"+++ National Enquirer: hacKNology may be part of deep state "\
|
||||
"+++ Disclaimer: This IS fake news! (says a cretan) "
|
||||
|
||||
lenmsg = len(msg)
|
||||
scroll_x = 500 # Scroll text background offset
|
||||
|
||||
|
@ -76,8 +72,8 @@ scr_width = 40 # Initial (full) width
|
|||
scr_sign = -1 # Start shrinking
|
||||
alpha = 0.5 # 0.5 (0..1)
|
||||
beta = (1.0 - alpha)
|
||||
x_offset = 16
|
||||
y_offset = 16
|
||||
x_offset = 6
|
||||
y_offset = 12
|
||||
|
||||
# Prepare background 'greenscreen'
|
||||
if alternate_background != None:
|
||||
|
@ -135,24 +131,18 @@ def do_alternate_background(current_frame,background_frame,alternate_frame):
|
|||
lower_black = np.array([0, 0, 0])
|
||||
upper_black = np.array([80, 80, 80])
|
||||
mask = cv2.inRange(delta_frame, lower_black, upper_black) # Yields black&white
|
||||
#sys.stdout.buffer.write(mask.tobytes())
|
||||
|
||||
# test next: hull = cv.convexHull(cnt)
|
||||
|
||||
# Attn.: We're operating on an inverse mask!
|
||||
# dilate actually increases (white) background
|
||||
# erode actually increases (black) foreground
|
||||
kernel2 = np.ones((5,5),np.uint8) # Clear artefacts
|
||||
# erode actually increases (black) foreground
|
||||
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) # Clear artefacts
|
||||
mask = cv2.dilate(mask,kernel2,iterations=1)
|
||||
|
||||
#kernel = np.ones((63,63),np.uint8) # 31 ok
|
||||
kernel = np.ones((9,9),np.uint8) # 31 ok
|
||||
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(9,9)) # Clear artefacts
|
||||
mask2 = cv2.erode(mask,kernel,iterations=7)
|
||||
#sys.stdout.buffer.write(mask2.tobytes())
|
||||
|
||||
kernel2 = np.ones((3,3),np.uint8) # 9,23 ok
|
||||
kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)) # Clear artefacts
|
||||
mask3 = cv2.dilate(mask2,kernel2,iterations=1)
|
||||
#sys.stdout.buffer.write(mask3.tobytes())
|
||||
|
||||
masked_image = np.copy(current_frame)
|
||||
masked_image[mask3 != 0] = [0, 0, 0] # From foreground take modified part (us!)
|
||||
|
@ -177,19 +167,17 @@ except:
|
|||
print("*** Can't open webcam!",file=sys.stderr)
|
||||
exit(-2)
|
||||
|
||||
print("Please take your chair & get out of the picture!\nWait 5s for continuation message ...",file=sys.stderr)
|
||||
time.sleep(5) # Time for operator to disappear!
|
||||
print("1. Please pick your chair & get out of the picture together!\n2. Wait 5s for continuation message ...",file=sys.stderr)
|
||||
time.sleep(3) # Time for operator to disappear!
|
||||
if alternate_background != None: # Shall we provide an alternative background?
|
||||
for i in range(1,75): # Warmup skip ...
|
||||
for i in range(1,75): # Warmup skip ... (~2s)
|
||||
ret, background_frame = cap.read()
|
||||
if ret!=True:
|
||||
print("*** Can't create background frame!",file=sys.stderr)
|
||||
exit(-3)
|
||||
|
||||
print("Thank you! You may enter webcam range again ...",file=sys.stderr)
|
||||
cv2.imshow('Empty room', background_frame)
|
||||
cv2.waitKey(0)
|
||||
cv2.destroyAllWindows()
|
||||
print("\x073. Thank you! You may enter webcam range again ...\n"\
|
||||
"4. Start your webcam application & connect to the virtual camera\n"\
|
||||
"5. Press [Ctrl][C] to abort ...",file=sys.stderr)
|
||||
|
||||
while(cap.isOpened()):
|
||||
try:
|
||||
|
@ -205,19 +193,19 @@ while(cap.isOpened()):
|
|||
scr_width = scr_width + scr_sign
|
||||
if scr_width <= 4:
|
||||
scr_sign = 1 # Start increasing
|
||||
if scr_width >= 60:
|
||||
if scr_width >= 100:
|
||||
scr_sign = -1 # & shrinking again
|
||||
src2 = cv2.resize(src1, (scr_width,76)) # w/h
|
||||
src2 = cv2.resize(src1, (scr_width,60)) # w/h
|
||||
overlay_image_alpha(frame,
|
||||
src2[:, :, 0:3],
|
||||
(x_offset+((60-scr_width)//2), y_offset),
|
||||
(x_offset+((100-scr_width)//2), y_offset),
|
||||
src2[:, :, 3] / 255.0)
|
||||
|
||||
frame4 = cv2.cvtColor(frame,cv2.COLOR_BGRA2RGB) # Correct color space
|
||||
|
||||
# Emblem subtext
|
||||
cv2.putText(frame4, "hacKNnology TV",
|
||||
(4,y_offset+76), # x,y
|
||||
(4,y_offset+62), # x,y
|
||||
(cv2.FONT_HERSHEY_DUPLEX), # Font
|
||||
0.4, # Scaling
|
||||
(255, 255, 255), # RGB
|
||||
|
@ -302,7 +290,7 @@ while(cap.isOpened()):
|
|||
(640,440), # x2,y2
|
||||
(200,200,200), # Color
|
||||
1) # Thickness
|
||||
scroll_x = scroll_x - 4
|
||||
scroll_x = scroll_x - 6
|
||||
if scroll_x < -lenmsg*6*3: # was: -500 ...
|
||||
scroll_x = 500
|
||||
#cv2.putText(frame4, 'scroll_x:'+str(scroll_x),
|
||||
|
@ -358,5 +346,5 @@ while(cap.isOpened()):
|
|||
break
|
||||
|
||||
cap.release()
|
||||
print("\n<<< funcam terminated. >>>",file=sys.stderr)
|
||||
print("\n<<< funcam terminated. >>>\n",file=sys.stderr)
|
||||
|
||||
|
|
15
virtcam.sh
15
virtcam.sh
|
@ -5,7 +5,8 @@
|
|||
# History:
|
||||
# --------
|
||||
# 05.05.20/KQ Initial version
|
||||
# 09.05.20/KQ Automatic virtual port detection (via getvirtualvideo.py)
|
||||
# 09.05.20/KQ Automatic virtual port detection (via getvirtualvideo.py), several fixed values turned into parameters
|
||||
# 12.05.20/KQ Local RSS feed added, more parameters ...
|
||||
#
|
||||
# 1. Install akvcam virtual camera devices
|
||||
# 2. Activate (cv) environment script
|
||||
|
@ -19,9 +20,10 @@
|
|||
|
||||
echo "Running virtcam ..."
|
||||
NAMEPLATE="Expert (+++)"
|
||||
# NAMEPLATE="kaqu (Klaus)"
|
||||
WEBCAM=2
|
||||
|
||||
cd ~/cv
|
||||
echo "Installing video4 (output) / video5 (capture) virtual devices ..."
|
||||
echo "Installing virtual devices ..."
|
||||
ls /dev/video? >videolist1.txt
|
||||
cd ~/akvcam/src
|
||||
sudo modprobe videodev
|
||||
|
@ -32,15 +34,16 @@ echo "Starting 'stream modifier' application ..."
|
|||
echo "Activating (cv) environment ..."
|
||||
source ~/cv/bin/activate
|
||||
cd ~/cv
|
||||
PWD=`pwd`
|
||||
ls /dev/video? >videolist2.txt
|
||||
CAMPORT=`python3 getvirtualvideo.py videolist`
|
||||
echo "1st virtual video port is: " $CAMPORT
|
||||
echo "Actual webcam hardware assumed as: /dev/video0"
|
||||
echo "Actual webcam hardware assumed as: /dev/video$WEBCAM (may require adjustment)"
|
||||
echo "*** For best video conference experience (currently, 5/2020) use chromium-browser ..."
|
||||
|
||||
# alternate background (beta) not activated by default
|
||||
# python3 funcam.py 0 $NAMEPLATE "https://www.heise.de/security/rss/news-atom.xml" alternate_background.jpg > $CAMPORT # webcam assumed as /dev/video0
|
||||
python3 funcam.py 0 "$NAMEPLATE" "https://www.heise.de/security/rss/news-atom.xml" > $CAMPORT # webcam assumed as /dev/video0
|
||||
python3 funcam.py $WEBCAM "$NAMEPLATE" "file://$PWD/FakeNews.xml" > $CAMPORT
|
||||
#python3 funcam.py $WEBCAM "$NAMEPLATE" "file://$PWD/FakeNews.xml" alternate_background.jpg > $CAMPORT
|
||||
|
||||
echo "Removing virtual (camera) devices ..."
|
||||
sudo rmmod akvcam.ko
|
||||
|
|
Loading…
Reference in New Issue