Archive for April, 2012

Technical report: A Cotangent Laplacian for Images as Surfaces

Monday, April 23rd, 2012

A Cotangent Laplacian for Images as Surfaces
We decided to write up a quick, 2 page technical report about some ideas we’ve had in the last year.

Abstract
By embedding images as surfaces in a high dimensional coordinate space defined by each pixel’s Cartesian coordinates and color values, we directly define and employ cotangent-based, discrete differential-geometry operators. These operators define discrete energies useful for image segmentation and colorization.

AaAHhhhhhhhh!Bob Saget.

Thursday, April 19th, 2012

aaahhhhhhhhhhh bob saget http://alecjacobson.com/art/digital/ http://alecjacobson.com/art/

Getting raw data from an image of a chart

Wednesday, April 18th, 2012

I found this chart of CHF to USD conversion rates over the last 730 days online, but couldn’t easily find the data behind it:
chf to usd from april 2010 to april 2012

So I grabbed a screenshot and applied some thresholding in photoshop to get an 730 pixel-wide image of the data line:
chf to usd from april 2010 to april 2012 thresholded data line

Then using the following matlab calls I extracted the data:


im = imread('chfusd-04-2010-04-2012-thresh.png');
[I,J] = find(any(~im,3));
DM = sparse(I,J,size(im,1)-I);
D = max(DM);
minD = 0.96;
maxD = 1.39;
D = D/max(D(:))*(maxD-minD)+minD;

Which I can then replot any way I like:
chf to usd from april 2010 to april 2012 matlab plot

Linking against static library using Eigen produces many direct access ... to global weak symbol warnings

Friday, April 13th, 2012

Our group builds a static library of useful functions implemented using the Eigen matrix library in C++. We build the library with a standard Makefile and gcc. But when I try to link against this library in an Xcode project (which also used Eigen) I got many warnings from the linker of the form:


ld: warning: direct access in void Eigen::internal::computeProductBlockingSizes<float, float, 4>(long&, long&, long&)to global weak symbol Eigen::internal::manage_caching_sizes(Eigen::Action, long*, long*)::m_l2CacheSizemeans the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.

There seem to be no problems at runtime, but nonetheless it’s annoying to have so many warnings.

To make the warnings go away, I went to my project settings in Xcode and made sure that Symbols Hidden by Default was set to No.

Xcode symbols hidden by default

Show \textwidth and \linewidth values in latex

Wednesday, April 11th, 2012

Here’s a snippet you can paste into your latex document to reveal the values of \textwidth and \linewidth printed into your document. First include this in your header:


\usepackage{layouts}

Then in your content someplace:


textwidth: \printinunitsof{in}\prntlen{\textwidth}

linewidth: \printinunitsof{in}\prntlen{\linewidth}

Find minimum non-zero entry in sparse matrix

Wednesday, April 4th, 2012

Using a sparse matrix to store a weighted adjacency matrix, I found myself trying to grad the minimal non-zero entry per row. This is a little tricky since taking min will just give the first zero (and obviously taking max of the inverse also returns 0).

Let your sparse matrix be:


A = sprand(10,10,0.5)-sprand(10,10,0.1);

This site proposes filling the zero entries with inf.


A(~A) = inf;
[mA,mI] = min(A);

But this turns our sparse matrix into a dense one. As A gets big this becomes a disaster.


[sA,sI] = sort(A,'descend');
[I,J,V] = find(sA);
msI = max(sparse(I,J,I));
mA = sA(sub2ind(size(A),msI,1:size(A,1)));
mI = sI(sub2ind(size(A),msI,1:size(A,1)));

Now, try this for 10000 by 10000 A with an average of 6 non-zeros per column. This replace with infs method takes crashed my matlab. So now try this for a 2500 by 2500 A with an average of 6 non-zeros per row. The replace with infs method takes 40.5 seconds, first converting the matrix to full format then replacing with infs does a lot better at 0.08 seconds, but the truly sparse method only takes 0.035 seconds.

Update:
Even another way to do it, which avoids the sort:


  [AI,AJ,AV] = find(A);                                                                                   
  A_i = sparse(AI,AJ,AV.^-1,size(A,1),size(A,2));                                                         
  [maxA_i,maxI_i] = max(A_i);                                                                             
  [minA,minI] = min(A);                                                                                   
  minA(minA==0) = inf;                                                                                    
  mA = [maxA_i.^-1;minA];                                                                                 
  [mA,J] = min(mA);                                                                                       
  mI = [maxI_i;minI];                                                                                     
  mI = mI(sub2ind(size(I),J,1:size(mI,2)));