Sunday, March 29, 2020

FFMpeg Dynamic Splatter Effect


In past posts we've demonstrated overlays and masks that can result in some pretty cool effects.  I vaguely recall a dynamic splatter effect where a photo (or video) was masked by a fluid mask and thought I'd spend some time trying to replicate it.  Here's what I found.

Let's spoil the reveal and jump to what we are trying to accomplish;

First step is to generate or steal the makings of a dynamic mask.  Water or fire seems a good fit, so browsed around YouTube to find something we could work with and this one caught my eye;


We can transform this splash effect upon a white background by performing pixel thresholding like this;
$ ffmpeg -i splash.mp4 -filter_complex "format=gray,geq=lum_expr='if(lte(lum(X,Y),128),255,0)'" -an -t 50 mask.mp4

Resulting in this:



Let's create our background image that we'll apply the mask to;
$ ffmpeg -loop 1 -t 50 -i image01.jpg -y image01.mp4

In our final step we'll apply the mask.  Since the mask region is an RGB video with white (255) pixels representing visible regions and black (0) regions indicating opaque we can and the video pixels to get the final result.

$ ffmpeg -i image01.mp4 -i mask.mp4 -filter_complex "[1:0] setdar=dar=1,format=rgba [a]; [0:0]setdar=dar=1,format=rgba [b]; [b][a]blend=all_mode='and'" -y clip.mp4


Apply some audio, repeat the video to fit to the audio length and you've got the resultant video.

Cheers.

Sunday, March 22, 2020

Command Line Processing with Popt

General practice for writing flexible applications lend toward the ability to specify command-line arguments to tailor the behavior of your application. For instance, a common practice of specifying -v to enable a verbose mode where debugging information is echoed as your application runs. Specifying a unique port for networking applications, or enablement/disablement of an application gui are two other examples that are common. Since command line arguments can take the flavor of integer, floats, doubles, strings...the code for parsing these arguments can be far from simple. Tailoring flexible parsers every time you develop an application is labor-intensive and a waste of time if a general mechanism were available.

Lucky for us, such a mechanism does exist; namely the Popt library.

Start by installing the Popt package:
$ sudo apt-get install libpopt-dev

A short example of an application which uses the library follows:

 1  #include <popt.h>
 2  #include <stdio.h>
 3  #include <stdlib.h>
 4
 5  int main(int argc, char **argv) {
 6          /* option parsing variables */
 7          char ch;
 8          poptContext opt_con;   /* context for parsing command-line options */
 9          char *extra_arg;
10          static int i=0;
11          static char *s="";
12          static float f=0.0;
13          static double d=0.0;
14          int verbose=0;
15
16          static struct poptOption options_table[] = {
17                  { "integer", 'i', POPT_ARG_INT, &i, 'i', "grab an integer", "INT" },
18                  { "string", 's', POPT_ARG_STRING, &s, 's', "grab a string", "STRING" },
19                  { "float", 'f', POPT_ARG_FLOAT, &f, 'f', "grab a float", "FLOAT" },
20                  { "double", 'd', POPT_ARG_DOUBLE, &d, 'd', "grab a double", "DOUBLE" },
21                  { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "enable verbose", "" },
22                  POPT_AUTOHELP
23                  { NULL, 0, 0, NULL, 0 } /* end-of-list terminator */
24          };
25
26          opt_con = poptGetContext(NULL, argc, (const char **)argv, options_table, 0);
27
28          /* Now do options processing */
29          while ((ch = poptGetNextOpt(opt_con)) >= 0) {
30                  printf("between while & switch: ch = %c\n", ch);
31                  switch (ch) {
32                          case 'i':
33                                  printf("handling 'i' option.\n");
34                                  break;
35                          case 's':
36                                  printf("handling 's' option.\n");
37                                  break;
38                          case 'f':
39                                  printf("handling 'f' option.\n");
40                                  break;
41                          case 'd':
42                                  printf("handling 'd' option.\n");
43                                  break;
44                          case 'v':
45                                  printf("handling 'v' option.\n");
46                                  verbose = 1;
47                                  break;
48                  }
49          }
50
51          if (ch < -1) {   

52                  // the user specified an invalid option, tell them   
53                  poptPrintHelp(opt_con, stderr, 0);       
54          }       
55       
56          /* non-option args */       
57          while (extra_arg = (char *)poptGetArg(opt_con)) {       
58                  printf("extra arg: %s\n", extra_arg);       
59                  exit(1);       
60          }       
61       
62       
63          /* cleanup */       
64          poptFreeContext(opt_con);       
65       
66  printf("(%s:%d) i = %d\n",__FILE__,__LINE__,i);       
67  printf("(%s:%d) s = '%s'\n",__FILE__,__LINE__,s);       
68  printf("(%s:%d) f = %f\n",__FILE__,__LINE__,f);       
69  printf("(%s:%d) d = %lf\n",__FILE__,__LINE__,d);       
70  printf("(%s:%d) v = %d\n",__FILE__,__LINE__,verbose);       
71       
72       
73    return EXIT_SUCCESS;       
74  }


You compile and link the application by:
g++ -Wall   main.o  -lpopt -o main


An added bonus of using this application is the automatic introduced interfaces for a brief and more verbose help descriptions.


~/Desktop/sourceCode/C/popt$ ./main --help
Usage: main [OPTION...]
-i, --integer=INT       grab an integer
-s, --string=STRING     grab a string
-f, --float=FLOAT       grab a float
-d, --double=DOUBLE     grab a double
-v, --verbose           enable verbose

Help options:
-?, --help              Show this help message
--usage                 Display brief usage message



~/Desktop/sourceCode/C/popt$ ./main --usage
Usage: main [-v?] [-i|--integer INT] [-s|--string STRING] [-f|--float FLOAT]
      [-d|--double DOUBLE] [-v|--verbose] [-?|--help] [--usage]



The heart of the library lies with proper initialization of the popt structure which is defined as follows:

struct poptOption {
  const char * longName;  
  char shortName;        
  int argInfo;
  void * arg;            
  int val;                
  const char * descrip;  
  const char * argDescrip;
};

The ability to specify either a long or short argument name is common practice; -h or --help is a common example of this form.

The long and short forms are specified as the 1st and 2nd element in the popt structure. The 3rd and 4th specify of what type the following argument consists of as well as the address in which the value will be stored. The 6th and 7th arguments specify the argument description and argument field name which is displayed in the help and brief. The 5th field is a bit of a mystery at this time.

That's all for now.

Sunday, March 15, 2020

Python Progress Bar


Was recently writing some python to process some test cases.  One long'ish testcase would benefit from a progress bar, slapped one together below.

One thing to note, progress doesn't allow going backwards, but indicates in ASCII text the current progress by writing characters and a series of backspaces.



#!/usr/bin/python
import time
import sys
 
class ProgressBar():
  barLen_=0;
  progress_=0;
  def __init__(self,N=10):
    self.barLen_=N;
    print '['+' '*self.barLen_+']',
    print '\b'*(self.barLen_+2),
  def setProgress(self,x):
    sys.stdout.flush();
    k=int(x/100.0*self.barLen_);
    if (k > self.progress_):
      update='\b'+'.'*(k-self.progress_);
      print update,
      self.progress_=k;

N=50
p=ProgressBar(N);

for i in range(0,101):
  p.setProgress(i);
  time.sleep(.05);

The result is of the form: 

user@river:~$ ./pBar 
[..............                                  ] 
Enjoy.

Sunday, March 8, 2020

Your Permanent Record


My school years were an amazing era, the enforcement of personal responsibility in my earliest of years was first upheld by teachers delivering a quick, but public, swatting on the butt when you were misbehaving.  In later years your compliance was enforced by threats of negative entries in 'your permanent record'.

The legendary permanent record was advertised as this global report of what a good (or bad) kid you were, perhaps a series of characteristics each with a score (1-10)...we'd really never know.  Denial of future job prospects, college admissions,...all lie in the wake of a negative record.  As we grew, we later found that no such record existed.  Mind blown; all the bad things we did would be left behind when we left school, a blank slate at our new school/company/fellowship.

Who would have thought that the concept of a permanent record would one-day exist, the concept was simply ahead of it's time.  Today, it takes the form as a Social Credit System.

The social credit system has privacy advocates up in arms for good reason, as it attempts to apply a grade to individuals based on their trustworthiness.  Its financial goal is to better assess whether a person is financially responsible, its social goal...to reward good behavior and punish bad behavior.  Personally, I'm torn; while I value privacy, I also observe (and conduct) bad behaviors on a daily basis.  Unless you believe in karma or the ever-after, you infrequently see dick-heads get their just desserts. Perhaps a social credit system would serve up justice and an ever-watching judge would reduce bad behaviors. /shrug

Dangerous slope, potential to be misused, and who's to judge...I'm not embracing the idea, but I can see how one could get there.

I struggle with this idea, and am drawn to one of it's heaviest criticisms; the ?right? to personal privacy.  But what is privacy?  What should be private, and what is public?  Where is the line?

For you, personally; have you ever thought about where the line for privacy should be?  Is the desire to preserve privacy a defensive action to hide stuff you're embarrassed about or more of an ideal concept.  If you privately donated $10,000 to a Red Cross bucket only to later be identified, would you have the same response to being identified as a drunk pedestrian who puked in the same bucket?  The line to privacy is likely personal and I'm not sure I myself have a clear line in my head.  Perhaps this post will help me reconcile my own privacy boundary.

Let's first look at the motivation for a Social Credit System, or peeking into one's privacy.

Let's say you're set up on a blind date.  Do you observe your dates privacy 100%, or do you challenge it somewhat?  Given the opportunity, would you ask their friends what they were like?  Would you ask their exes how they were treated?  Would you want to know if they were a good employee, have held a stable job?  Would you want to know if they were financially stable, in good standing with their landlord, have a criminal record?  Would you want to know how they treat their servers when out dining?  Would you want to know if they had an STD?...  Would you want to know any of these things, some of them, or none of them?  The world is full of dating advise that suggests knowing these things to avoid a relationship that is doomed to failure.  Each inquiry into your date could be considered an invasion of their privacy.

What if you are a parent looking for a day-care provider?  Would you want to know if they were a reckless driver, hot-headed, or an anti-vaxer?  Would you want to know if they frequently screamed at their own kids, had a criminal record, was an occultist, or their preferred pastime was doing lines in the nightclub stalls?  What if they have pedo-tendencies, but have never been charged/convicted?

How about as an employer; would you want to know if your perspective employee has a history of flipping-the-bird to fellow travelers, treats shouting obscenities in an open stadium as their main hobby, is an founding member of the alt-left, alt-right, local nazi party or any other form of extremist?

As a consumer of such privacy info, would you pry?  Or, perhaps you are in the fleeting minority of believing that people are inherently good.  The consequences are mostly yours to bear; it'll be you that needs to pry a blind-date deadbeat from your memory and potentially off your couch.  It'll be you that will deal with any consequences of leaving your kid with a psycho.  And, it'll be you that needs to publicly apologize for an employee that brings Internet-worthy shame to your business.  Most people I know would dig at least a little beforehand _if_ the information was readily available.

But where is the line separating private from public?  As an individual, where would you draw the privacy line?  What is private, what is public....if you, and you alone could define the boundary?  Forget current conventions, forget legal definitions,...forget it all for now, with a clean slate....where would you draw the line?
  • A drunken melt-down on a commercial airline -- private/public?
  • Public participation in an extremist rally (alt-left, alt-right, nazi, KKK...) -- private/public?
  • Privately tutoring underprivileged kids in STEM -- private/public?
  • Aggressively driving while flipping the bird to other drivers -- private/public?
  • Volunteering to foster abandoned pets -- private/public?
  • Sharing your personal opinion on a topic on the Internet while using your real name-- private/public?
  • Sharing opinions (perhaps hostile) on the Internet while using an anonymous name -- private/public?
  • Beating your mate/kids behind closed doors while avoiding criminal charges -- private/public?
  • Obsessing with executing physical harm on others -- private/public?
  • Private participation in an extremist group -- private/public?
  • Personal nude selfies -- private/public?
  • .... (I will avoid going darker)

If you're like me, you want to define clear boundaries.  Some distinctions are easier, others are extremely hard.  Equally, if you're like me, you'll find it nearly difficult to do so.  We criticize public figures and the legal profession for drawing these boundaries, perhaps we even trust their judgement.  More than likely though, we will simply ignore it....put it in the box of way too hard problems to solve along with countless math problems from the past, never to be returned to.

So, I continue to be torn on the topic.  I continue to wish dick-ish people would be punished for dick-ish behavior and good people are rewarded.  I don't want people prying into my personal life, yet understand the motivations for doing so.  I want to define an line that distinguishes between private/public but it continues to elude me.

I only wish that your journey to do so is found to be easier.  Good luck!

Sunday, March 1, 2020

Technical Tastemakers


Geek Chic, two words that I never thought would go together but it seems as STEM becomes fashionable everyone wants a piece.  The term 'technologist' is another term that makes it's rounds, oftentimes self-proclaimed by those who lack a technical degree but want to be identified in the same group.

Most often, someone touting the title 'technologist' that lack technical chops are simply tolerated in the same manner as a toddler pretending to be Superman, it's cute and can be flattering.  Those that once scoffed at math and science now see opportunity in the fashionable field of STEM and want to be part of it.  Mostly, this of little consequence, but sometimes it's hurtful to the progression of tech and a slap in the face to those who have dedicated their lives to the profession.

Let's focus on one example, namely Google I/O.  Entry into such a technical conference where the latest tech and products are showcased were originally intended for true tech-heads.  The possibility of meeting top-tier engineers from across the world has the potential of supercharging technical pursuits.  Sadly, when non-technical folks take the floor and leave deserving techies riding the bench, the game suffers.  Fortune 500 companies get exclusive invites to participate and unfortunately oftentimes these seats are snagged by wanna-be's.  In two words, that sucks.

The same result can take place at a larger scale.  Technology should prevail under the 'best tech wins' criteria, and when the audience is purely engineering and scientists if often does.  As marketing and popularity contests begin muddying the waters the discipline loses.

Let's look at one more example, perhaps the most important one to our future.  STEM *needs* people and I'm always encouraged to see those interested in its pursuit.  I am however *concerned* when they are misled or sold a false bill-of-sale.  'Influencers' are a-many, typically attractive young dynamic folks that spew 'self-taught coder' and 'learn to code' curriculum for a low, low price.  Engineering is hard; period.....full-stop.  Picking up a 'Java for Dummies' book and creating a simple app is only a small step in the process.  I've changed hundreds of spark-plugs in my time, yet I don't call myself a mechanic.  I've read Harry Potter, that doesn't make me a wizard.  I've written dozens or hundreds of papers and that still doesn't make me a professional writer.  Yet, somehow there has evolved this industry or accepted standard for the sale of 'silicon snakeoil', and unfortunately the audience is ill-prepared to identify it as such.

I'd invite you to go on to YouTube, Instagram, Twitter and search for such personalities.  Go ahead....I'll wait.  Now, if they are transparent about the topic, look for their qualifications.  You'll likely not find  veterans of software development, and are far more likely to find a career in marketing, sales or such followed by a short path to learning to code, followed by a strong focus of becoming an 'influencer' or the founder of yet another 'code camp'.

I'll avoid calling out specific names, but here is what i did.  Since YouTube is rich with 'learn to code prophets' i did a quick search specifically for 'learn to code' and got just shy of a bazillion hits.  Then, identify each person and look for them on LinkedIn.  Most of the folks have 1-3 years worth of experience in software development, yet somehow feel qualified in telling the world how to be 'like them'.  If your goal is to begin a career in X, you probably shouldn't be taking advise from a 1-3 year drop-out of X; a bit harsh, but 100% truth.  Young engineers have an important part to share about the the journey, namely many challenges and feelings the long-in-the-tooth colleagues have long forgotten.  Long in the tooth engineers have forgotten much of this, fresh faces can contribute on such important matters.  But, young engineers don't yet have the long-term perspective of a long-term engagement in the field.  People are signing up for long-term career paths along with a financial budget that of an exotic car (or house) with a fraction of information and it makes me sad.

I love this career, always have, always will, and I'm encouraged to see people expressing interest in the career but genuinely terrified that people are handing over money (unnecessarily) to folks that are not qualified nor honest in their intentions.  Worse than the financial loss, people are dedicating a significant amount of time and emotional energy with the strong probability that they may fail after being convinced by ill-experienced 'professionals' how easy it is.  Even worse, dedicating your time and energy only to find that the career is nothing they thought it was.

/shrug