“Bijective mappings with generalized barycentric coordinates: a counterexample” published in JGT

April 22nd, 2014

bijective barycentric coordinates counterexample

My little proof that any generalized barycentric coordinates can create a non-injective mapping (i.e. you give me a scheme for weights then I can give you a configuration that creates a deformation with flips) was published in the Journal of Graphics Tools. If you don’t have access, then why not just take a look at the tech report. The proofs are just slightly different, only amounting to satisfying different tastes.

Qt application launched in background, not stealing focus

April 22nd, 2014

We’re building a Qt executable (not an app bundle) with cmake. When running it feels like an application, dock icon, menu bar and all, but when it’s first launched from the command line with something like:

./my_app_exec

The application opens behind the terminal. The focus stays with the terminal. This was frustrating because then each time I launch the application I need to CMD+SHIFT+TAB to get to the application.

Here’s a dirty hack workaround. In my main function just after main_window.show() or whatever I add a bit of apple-specific applescript to do the alt tabbing for me:

mainWin->show();
#ifdef __APPLE__
    system("osascript -e 'tell application \"System Events\" "
      "to keystroke tab using {command down, shift down}'");
#endif

No `gdb` in OS X 10.9, Mavericks

April 21st, 2014

Use lldb, even works with binaries compiled with gcc.

Matlab’s mex can’t find std headers

April 18th, 2014

Trying to compile the ecos mex files I ran into the following errors:

In file included from /opt/local/lib/gcc47/gcc/x86_64-apple-darwin13/4.7.3/include-fixed/syslimits.h:7:0,
                 from /opt/local/lib/gcc47/gcc/x86_64-apple-darwin13/4.7.3/include-fixed/limits.h:34,
                 from ../external/SuiteSparse_config/SuiteSparse_config.h:45,
                 from ../external/ldl/include/ldl.h:11,
                 from ../external/ldl/src/ldl.c:157:
/opt/local/lib/gcc47/gcc/x86_64-apple-darwin13/4.7.3/include-fixed/limits.h:169:61: error: no include path in which to search for limits.h
In file included from ../external/ldl/include/ldl.h:11:0,
                 from ../external/ldl/src/ldl.c:157:
../external/SuiteSparse_config/SuiteSparse_config.h:46:20: fatal error: stdlib.h: No such file or directory
compilation terminated.

    mex: compile of ' "../external/ldl/src/ldl.c"' failed.

Turns out this has nothing to do with ecos, rather I had upgraded my OS since installing matlab. I need to replace 10.7 with 10.9 in my /Applications/MATLAB_R2013b.app/bin/mexopts.sh file. Then everything compiled fine.

The offending flags were:

-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/ -mmacosx-version-min=10.7

And the correct versions were:

-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/ -mmacosx-version-min=10.9

Interactive image comparison with sliding splitter in MATLAB

April 16th, 2014

Wojciech Jarosz has nice interactive comparisons on his website. I wanted to have a similar feature in matlab. Here’s a little function to do just that:

function [ph,ih] = sliding_comparison(A,B)
  % SLIDING_COMPARISON Create a figure which allows the user to mouse over and
  % move a sliding splitter to compare two images interactively.
  %
  % Inputs:
  %   A  h by w by c left image (should be double)
  %   B  h by w by c right image (should be double)
  % Outputs:
  %   ph  handle to plot of separator line
  %   ih  handle to image line
  %
  function C = split(A,B,x)
    x = max(min(x,size(A,2)),1);
    C = [A(:,1:round(x)-1,:) B(:,round(x):end,:)];
  end

  function onmove(src,ev)
    % get current mouse position, and remember old one
    pos=get(gca,'currentpoint');
    x = pos(1,1,1);
    if ishandle(ih) && ishandle(ph)
      set(ph,'XData',repmat(x,1,2));
      set(ih,'CData',split(A,B,x));
    else
      % Clean up
      set(gcf,'windowbuttonmotionfcn',old_onmove);
    end
    drawnow
  end

  w = size(A,2);
  h = size(A,1);
  % `imshow` will clamp but `set(...,'CData',...)` will not
  clamp = @(X) max(min(X,1),0);
  A = clamp(A);
  B = clamp(B);

  x = w/2;
  ih = imshow(split(A,B,x));
  hold on;
    ph = plot([x;x],[0;h],'LineWidth',2);
  hold off;

  old_onmove = get(gcf,'windowbuttonmotionfcn');
  set(gcf,'windowbuttonmotionfcn',@onmove);
end

So, say you have your image in im and your depth image in D then:

sliding_comparison(im,repmat(D,[1 1 3]))

Then you’ll see something like:

octopus-sliding-splitter-image-comparison.gif

Enlarge matlab axis by a specific factor

April 8th, 2014

Here’s the code I use to double or enlarge the axis of a plot window by any factor. Say 150%:

a = axis;
axis(a+1.5*[a(1:2)-(a(1)+a(2))*0.5 a(3:4)-(a(3)+a(4))*0.5]);

Matlab is stalling after every command

April 1st, 2014

I ran into a strange issue that MATLAB was stalling for a long while each time I issued a command and took a long time to execute scripts. Seems the issue was that the current directory I was working in had over 30000 files. My guess is that this was causing the parser to freak out when searching for available functions. Anyway, moving these files (some generated data) to a subfolder not in the working path fixed the issue.

Convert all .mkv files in a directory to .mp4 for ipad

March 30th, 2014

Here’s a bash “one-liner” to convert all movie files in the current directory to a format that works with the ipad. It renames the files from .mkv to .mp4.

for f in *.mkv; do ffmpeg -i $f -acodec aac -ac 2 -strict experimental -ab 160k -s 1920x1080 -vcodec copy -f mp4 -threads 0 ${f%.*}.mp4; done

Bounded biharmonic weights in Communications of the ACM

March 26th, 2014

bbw in cacm

Our 2011 SIGGRAPH paper, “Bounded Biharmonic Weights for Real-Time Deformation”, is featured in the Research Highlights section of the April 2014 edition of the computer science magazine Communications of the ACM. This version of the paper has some updates that would have been anachronistic in the original paper and a more accessible introduction (at least we think so). The paper is prefaced by a technical perspective letter by Joe Warren.

Sort movies by existence in list of movie titles

March 24th, 2014

Using the bash script from my previous post I can generate a list of all movie titles on tehconnection.eu and store them as lines in a text file called tehconnection.eu. I wanted this to sift through a giant list of movies I had on an old external hard drive. This ruby script (save in sort_by_tehconnection.rb) to check my directories list of movies against the list from tehconnection and move the files that exist in that list into a separate directory (which I’ll then double check and delete).

Using the bash script from my previous post I can generate a list of all movie titles on tehconnection.eu and store them as lines in a text file called tehconnection.eu. I wanted this to sift through a giant list of movies I had on an old external hard drive. This ruby script (save in sort_by_tehconnection.rb) to check my directories list of movies against the list from tehconnection and move the files that exist in that list into a separate directory (which I’ll then double check and delete).

#!/opt/local/bin/ruby

require "levenshtein_distance.rb"
require 'fileutils'

look_dir='/Volumes/Senorita/DOCUMENTARIES/Feature Documentaries/'
found_dir='/Volumes/Senorita/DOCUMENTARIES/Feature Documentaries/tehconnection/'

#files_array=File.readlines('files.txt');
files_array=Dir.entries(look_dir).reject{|entry| entry == "." || entry == ".." || entry == ".DS_Store"};
teh_array=File.readlines('tehconnection.txt').collect {|l| l.gsub(/[.!?:';"]/,"").downcase.sub(/^the /,"").chomp};
teh_array = teh_array.inject([]) do |res,e|
  if e =~/([^\(]*) \(aka ([^\)]*)\)/
    res.concat([$1,$2]);
  else
    res.concat([e]);
  end
end
teh_map = [];
teh_array.each do |e| 
  i = e.length-1;
  if teh_map[i].nil?
    teh_map[i] = [];
  end
  teh_map[i] << e
end
acceptable_dist=2
min_dist=10000
min_teh=""
files_array.each do |orig_title|
  title=orig_title.sub(/ *\([^\(]*\)/,"")
  title.downcase!
  title.sub!(/\.[^\.]*$/,"")
  title.sub!(/^the /,"")
  title.gsub!("\"","")
  title.sub!(/^marx brothers - /,"")
  len = title.length;
  max_len = [len+acceptable_dist,teh_map.length-1].min;
  min_len = [len-acceptable_dist,0].max;
  puts "#{title}..."
  (min_len..max_len).each do |l|
    l_array = teh_map[l];
    found = false;
    if not l_array.nil?
      l_array.each do |teh_title|
        dist=levenshtein_distance(title,teh_title)
        if dist<acceptable_dist
          # found
          puts "  FOUND (#{orig_title}): #{teh_title} --> #{title}, #{dist}"
          FileUtils.mv(look_dir+"/"+orig_title,found_dir+"/"+orig_title);
          found = true;
          break;
        end
      end
    end
    if found
      break;
    end
  end
end