You are hereFeed aggregator

Feed aggregator


Variation on Connected Objects – Using Graphs

Matlab Image processing blog - 2017, April 6 - 12:35

Reader Uri Pe'er found an old post from 2011 about shortest paths in binary images, and he asked this follow-up question (paraphrased):

How can I determine if there is a path from one row to another in a binary image? And can I constrain the direction of movement along the path?

Last week I showed how to tackle this problem using imfill. Today I'm going to use a graph.

In December 2015 I wrote about how to create graphs based on the connectivity of image pixels, and I submitted some functions to the File Exchange to make it easy.

One of those functions is binaryImageGraph. Let's try it using one of the same images from my last post.

bw1 = imread('http://blogs.mathworks.com/steve/files/path-shapes-1.png'); imshow(bw1) g = binaryImageGraph(bw1) g = graph with properties: Edges: [180444×2 table] Nodes: [45880×3 table]

Each foreground pixel in the binary image corresponds to a graph node, so the total number of graph nodes is the same as the number of foreground pixels.

nnz(bw1) ans = 45880

The function plotImageGraph (from the same File Exchange submission) can be used to visualize the image graph.

plotImageGraph(g)

Zoom in to see the graph details in a small portion of the image.

axis([275 300 125 140])

Now let's figure out whether there are any graph paths connecting a row-100 pixels to a row-300 pixel. Note that binaryImageGraph stores the original foreground pixel locations in the graph's node table for purposes just like this. Here's what the node table looks like.

head(g.Nodes) ans = 8×3 table x y PixelIndex ___ __ __________ 121 76 57676 121 77 57677 121 78 57678 121 79 57679 121 80 57680 121 81 57681 121 82 57682 121 83 57683 row_100_nodes = find(g.Nodes.y == 100); row_300_nodes = find(g.Nodes.y == 300);

Next, use conncomp to find the connected components of the graph.

bins = conncomp(g);

For one of the graph nodes, bins(node) tells you which connected component that node belongs to.

unique(bins(row_100_nodes)) ans = 1

So the foreground pixels on row 100 all belong to the same connected component.

unique(bins(row_300_nodes)) ans = 1 2

The foreground pixels on row 300 belong to two different connected components. Since one of those the components is the same as for the row 100 pixels, that means there is path from row 100 to row 300.

Just like imfill, binaryImageGraph can take a custom connectivity matrix. We can use that to constrain the allowed paths. Let's try that with one of the other images I used last time.

bw3 = imread('http://blogs.mathworks.com/steve/files/path-shapes-3.png'); imshow(bw3) conn = [ 1 0 0 0 1 0 0 0 1 ]; g = binaryImageGraph(bw3,conn); plotImageGraph(g) axis([275 300 125 140])

Is there a constrained path from row 180 to row 250?

row_180_nodes = find(g.Nodes.y == 180); row_250_nodes = find(g.Nodes.y == 250); bins = conncomp(g); ~isempty(intersect(bins(row_180_nodes),bins(row_250_nodes))) ans = logical 0

No.

But what if we reverse the path constraint?

conn = [ 0 0 1 0 1 0 1 0 0 ]; g = binaryImageGraph(bw3,conn); plotImageGraph(g) axis([275 300 125 140]) row_180_nodes = find(g.Nodes.y == 180); row_250_nodes = find(g.Nodes.y == 250); bins = conncomp(g); ~isempty(intersect(bins(row_180_nodes),bins(row_250_nodes))) ans = logical 1

Yes, rows 180 and 250 are connected via a paths constrained to lie along the upper-right to lower-left diagonal.

\n'); d.write(code_string); // Add copyright line at the bottom if specified. if (copyright.length > 0) { d.writeln(''); d.writeln('%%'); if (copyright.length > 0) { d.writeln('% _' + copyright + '_'); } } d.write('\n'); d.title = title + ' (MATLAB code)'; d.close(); } -->


Get the MATLAB code (requires JavaScript)

Published with MATLAB® R2017a

about shortest paths in % binary images, and he asked this follow-up question (paraphrased): % % _How can I determine % if there is a path from one row to another in a binary image? And can I % constrain the direction of movement along the path?_ % % I showed how to tackle this problem using % . Today % I'm going to use a |graph|. % % In December 2015 I wrote about how to create graphs based on the % connectivity of image pixels, and I to make it easy. % % One of those functions is |binaryImageGraph|. Let's try it using one of % the same images from my last post. bw1 = imread('http://blogs.mathworks.com/steve/files/path-shapes-1.png'); imshow(bw1) %% g = binaryImageGraph(bw1) %% % Each foreground pixel in the binary image corresponds to a graph node, so % the total number of graph nodes is the same as the number of foreground % pixels. nnz(bw1) %% % The function |plotImageGraph| (from the same % ) can be used to visualize the image graph. plotImageGraph(g) %% % Zoom in to see the graph details in a small portion of the image. axis([275 300 125 140]) %% % Now let's figure out whether there are any graph paths connecting a % row-100 pixels to a row-300 pixel. Note that |binaryImageGraph| stores % the original foreground pixel locations in the graph's node table for % purposes just like this. Here's what the node table looks like. head(g.Nodes) %% row_100_nodes = find(g.Nodes.y == 100); row_300_nodes = find(g.Nodes.y == 300); %% % Next, use |conncomp| to find the connected components of the graph. bins = conncomp(g); %% % For one of the graph nodes, |bins(node)| tells you which connected % component that node belongs to. unique(bins(row_100_nodes)) %% % So the foreground pixels on row 100 all belong to the same connected % component. unique(bins(row_300_nodes)) %% % The foreground pixels on row 300 belong to two different connected % components. Since one of those the components is the same as for the row % 100 pixels, that means there is path from row 100 to row 300. % % Just like |imfill|, |binaryImageGraph| can take a custom connectivity % matrix. We can use that to constrain the allowed paths. Let's try that % with one of the other images I used last time. bw3 = imread('http://blogs.mathworks.com/steve/files/path-shapes-3.png'); imshow(bw3) %% conn = [ 1 0 0 0 1 0 0 0 1 ]; g = binaryImageGraph(bw3,conn); plotImageGraph(g) axis([275 300 125 140]) %% % Is there a constrained path from row 180 to row 250? row_180_nodes = find(g.Nodes.y == 180); row_250_nodes = find(g.Nodes.y == 250); bins = conncomp(g); ~isempty(intersect(bins(row_180_nodes),bins(row_250_nodes))) %% % No. % % But what if we reverse the path constraint? conn = [ 0 0 1 0 1 0 1 0 0 ]; g = binaryImageGraph(bw3,conn); plotImageGraph(g) axis([275 300 125 140]) %% row_180_nodes = find(g.Nodes.y == 180); row_250_nodes = find(g.Nodes.y == 250); bins = conncomp(g); ~isempty(intersect(bins(row_180_nodes),bins(row_250_nodes))) %% % Yes, rows 180 and 250 are connected via a paths constrained to lie along % the upper-right to lower-left diagonal. ##### SOURCE END ##### 3fb39edd0ee44d8bbc65ff98f003c70c -->

Categories: Blogs

How optimistic disaster stories can save us from dystopia

Cory Doctorow - 2017, April 5 - 03:37


I’ve got an editorial in this month’s Wired magazine about the relationship between the science fiction stories we read and our real-world responses to disasters: Disasters Don’t Have to End in Dystopias; it’s occasioned by the upcoming publication of my “optimistic disaster novel” Walkaway (pre-order signed copies: US/UK; read excerpts: Chapter 1, Chapter 2; US/Canada tour schedule).

The stories we tell ourselves about the way that the people around us will behave in times of crisis determines how we behave when things go wrong. Decades of science fiction that advanced the nonsensical proposition that our neighbors will come and eat us as soon as the lights go out has produced a widespread idea that disasters are when you should run away, far from the people who can help you (and can need your help). With optimistic disaster stories, I’m hoping to help people understand why they should bug in, not bug out, and help get things fixed and the rubble cleared away. It’s the difference between “disaster” and “dystopia.”



Since Thomas More, utopian projects have focused on describing the perfect state and mapping the route to it. But that’s not an ideology, that’s a daydream. The most perfect society will exist in an imperfect universe, one where the second law of thermodynamics means that everything needs constant winding up and fixing and adjusting. Even if your utopia has tight-as-hell service routines, it’s at risk of being smashed by less-well-maintained hazards: passing aster­oids, feckless neighboring states, mutating pathogens. If your utopia works well in theory but degenerates into an orgy of cannibalistic violence the first time the lights go out, it is not actually a utopia.

I took inspiration from some of science fiction’s most daring utopias. In Kim Stanley Robinson’s Pacific Edge—easily the most uplifting book in my collection—a seemingly petty squabble over zoning for an office park is a microcosm for all the challenges that go into creating and maintaining a peaceful, cooperative society. Ada Palmer’s 2016 fiction debut, Too Like the Lightning, is a utopia only a historian could have written: a multi­polar, authoritarian society where the quality of life is assured by a mix of rigid social convention, high tech federalism, and something almost like feudalism.

The great problem in Walkaway (as in those novels) isn’t the exogenous shocks but rather humanity itself. It’s the challenge of getting walkaways—the 99 percent who’ve taken their leave of society and thrive by cleverly harvesting its exhaust stream—to help one another despite the prepper instincts that whisper, “The disaster will only spare so many of its victims, so you’d better save space on any handy lifeboats, just in case you get a chance to rescue one of your own.” That whispering voice is the background hum of a society where my gain is your loss and everything I have is something you don’t—a world where material abundance is perverted by ungainly and unstable wealth distribution, so everyone has to worry about coming up short.

Disasters Don’t Have to End in Dystopias [Cory Doctorow/Wired]

Pre order Walkaway: US/UK

Read excerpts: Chapter 1, Chapter 2)

US/Canada tour schedule

Categories: Blogs

Variations on Connected Objects – Using imfill

Matlab Image processing blog - 2017, March 31 - 11:41

Reader Uri Pe'er found an old post from 2011 about shortest paths in binary images, and he asked this follow-up question (paraphrased):

How can I determine if there is a path from one row to another in a binary image? And can I constrain the direction of movement along the path?

That sounds fun. Let's give it a try.

I can think of several different approaches. Today I'm going to tackle it using imfill.

Here's a sample image I just drew up.

bw1 = imread('http://blogs.mathworks.com/steve/files/path-shapes-1.png'); imshow(bw1)

Let's use imfill to see if there is a path from any of the foreground pixels on row 100 to any of the foreground pixels on row 300. First, find the foreground pixels on those rows.

fg_cols_row_100 = find(bw1(100,:)); fg_cols_row_300 = find(bw1(300,:)); hold on plot(fg_cols_row_100,100,'b*') plot(fg_cols_row_300,300,'b*') hold off

Now let's perform an imfill operation starting from all the foreground pixels on row 100. Because imfill fills in background pixels, we need to complement the image first.

bw1a = ~bw1; imshow(bw1a) title('Complemented image')

Now perform the fill in the complemented image.

seed_pixels = [100*ones(numel(fg_cols_row_100),1) fg_cols_row_100']; bw1b = imfill(bw1a,seed_pixels); imshow(bw1b) title('Filled image')

Which pixels changed as a result of the fill?

bw1c = bw1b & ~bw1a; imshow(bw1c) title('Pixels changed by the fill operation')

If there are any foreground pixels on row 300 of bw1c, then that means row 100 is connected to row 300.

connected = any(bw1c(300,:)) connected = logical 1

Let's try the steps above on another image.

bw2 = imread('http://blogs.mathworks.com/steve/files/path-shapes-2.png'); imshow(bw2) title('Image 2') fg_cols_row_100 = find(bw1(100,:)); fg_cols_row_300 = find(bw1(300,:)); bw2a = ~bw2; seed_pixels = [100*ones(numel(fg_cols_row_100),1) fg_cols_row_100']; bw2b = imfill(bw2a,seed_pixels); bw2c = bw2b & ~bw2a; connected = any(bw2c(300,:)) connected = logical 0

So we have computed that there is no path connecting rows 100 and 300 in the second image.

OK, what about the second part of Uri's question? How do we constrain the path? For example, how do we constrain the problem to allow movement from the upper-left-to-lower-right diagonal?

We can do that by specifying a custom connectivity when we call imfill. Here's another sample image to test the concept.

bw3 = imread('http://blogs.mathworks.com/steve/files/path-shapes-3.png'); imshow(bw3) fg_cols_row_100 = find(bw3(100,:)); fg_cols_row_300 = find(bw3(300,:)); hold on plot(fg_cols_row_100,100,'b*') plot(fg_cols_row_300,300,'b*') hold off

You can specify a custom connectivity using a 3x3 matrix. Here is one that only allows movement along the upper-left-to-lower-right diagonal.

conn = [ 1 0 0 0 1 0 0 0 1 ];

Now use that connectivity matrix with imfill.

bw3a = ~bw3; seed_pixels = [100*ones(numel(fg_cols_row_100),1) fg_cols_row_100']; bw3b = imfill(bw3a,seed_pixels,conn); bw3c = bw3b & ~bw3a; imshow(bw3c)

The odd-looking shape above is the set of pixels reachable from foreground pixels on row 100 traveling only along the specified diagonal. With this constrained path, rows 100 and 300 are not connected.

connected = any(bw3c(300,:)) connected = logical 0

But what if we use the opposite diagonal for our path constraint?

conn = [ 0 0 1 0 1 0 1 0 0 ]; bw3b = imfill(bw3a,seed_pixels,conn); bw3c = bw3b & ~bw3a; imshow(bw3c)

You can see that rows 100 and 300 are still not connected. Let's try rows 180 and 250.

imshow(bw3) fg_cols_row_180 = find(bw3(180,:)); fg_cols_row_250 = find(bw3(250,:)); hold on plot(fg_cols_row_180,180,'b*') plot(fg_cols_row_250,250,'b*') hold off seed_pixels = [180*ones(numel(fg_cols_row_180),1) fg_cols_row_180']; bw3b = imfill(bw3a,seed_pixels,conn); bw3c = bw3b & ~bw3a; imshow(bw3c)

And rows 180 and 250 are connected.

connected = any(bw3c(250,:)) connected = logical 1

Next time I plan to take another look at this problem using MATLAB graph operations.

\n'); d.write(code_string); // Add copyright line at the bottom if specified. if (copyright.length > 0) { d.writeln(''); d.writeln('%%'); if (copyright.length > 0) { d.writeln('% _' + copyright + '_'); } } d.write('\n'); d.title = title + ' (MATLAB code)'; d.close(); } -->


Get the MATLAB code (requires JavaScript)

Published with MATLAB® R2017a

about shortest paths in % binary images, and he asked this follow-up question (paraphrased): % % _How can I determine % if there is a path from one row to another in a binary image? And can I % constrain the direction of movement along the path?_ % % That sounds fun. Let's give it a try. % % I can think of several different approaches. Today I'm going to tackle it using |imfill|. % % Here's a sample image I just drew up. bw1 = imread('http://blogs.mathworks.com/steve/files/path-shapes-1.png'); imshow(bw1) %% % Let's use |imfill| to see if there is a path from any of the foreground % pixels on row 100 to any of the foreground pixels on row 300. First, find % the foreground pixels on those rows. fg_cols_row_100 = find(bw1(100,:)); fg_cols_row_300 = find(bw1(300,:)); hold on plot(fg_cols_row_100,100,'b*') plot(fg_cols_row_300,300,'b*') hold off %% % Now let's perform an |imfill| operation starting from all the foreground % pixels on row 100. Because |imfill| fills in background pixels, we need % to complement the image first. bw1a = ~bw1; imshow(bw1a) title('Complemented image') %% % Now perform the fill in the complemented image. seed_pixels = [100*ones(numel(fg_cols_row_100),1) fg_cols_row_100']; bw1b = imfill(bw1a,seed_pixels); imshow(bw1b) title('Filled image') %% % Which pixels changed as a result of the fill? bw1c = bw1b & ~bw1a; imshow(bw1c) title('Pixels changed by the fill operation') %% % If there are any foreground pixels on row 300 of |bw1c|, then that means % row 100 is connected to row 300. connected = any(bw1c(300,:)) %% % Let's try the steps above on another image. bw2 = imread('http://blogs.mathworks.com/steve/files/path-shapes-2.png'); imshow(bw2) title('Image 2') %% fg_cols_row_100 = find(bw1(100,:)); fg_cols_row_300 = find(bw1(300,:)); bw2a = ~bw2; seed_pixels = [100*ones(numel(fg_cols_row_100),1) fg_cols_row_100']; bw2b = imfill(bw2a,seed_pixels); bw2c = bw2b & ~bw2a; connected = any(bw2c(300,:)) %% % So we have computed that there is no path connecting rows 100 and 300 in % the second image. % % OK, what about the second part of Uri's question? How do we constrain the % path? For example, how do we constrain the problem to allow movement from % the upper-left-to-lower-right diagonal? % % We can do that by specifying a _custom connectivity_ when we call % |imfill|. Here's another sample image to test the concept. bw3 = imread('http://blogs.mathworks.com/steve/files/path-shapes-3.png'); imshow(bw3) fg_cols_row_100 = find(bw3(100,:)); fg_cols_row_300 = find(bw3(300,:)); hold on plot(fg_cols_row_100,100,'b*') plot(fg_cols_row_300,300,'b*') hold off %% % You can specify a custom connectivity using a 3x3 matrix. Here is one % that only allows movement along the upper-left-to-lower-right diagonal. conn = [ 1 0 0 0 1 0 0 0 1 ]; %% % Now use that connectivity matrix with |imfill|. bw3a = ~bw3; seed_pixels = [100*ones(numel(fg_cols_row_100),1) fg_cols_row_100']; bw3b = imfill(bw3a,seed_pixels,conn); bw3c = bw3b & ~bw3a; imshow(bw3c) %% % The odd-looking shape above is the set of pixels reachable from % foreground pixels on row 100 traveling only along the specified diagonal. % With this constrained path, rows 100 and 300 are not connected. connected = any(bw3c(300,:)) %% % But what if we use the opposite diagonal for our path constraint? conn = [ 0 0 1 0 1 0 1 0 0 ]; bw3b = imfill(bw3a,seed_pixels,conn); bw3c = bw3b & ~bw3a; imshow(bw3c) %% % You can see that rows 100 and 300 are still not connected. Let's try rows % 180 and 250. imshow(bw3) fg_cols_row_180 = find(bw3(180,:)); fg_cols_row_250 = find(bw3(250,:)); hold on plot(fg_cols_row_180,180,'b*') plot(fg_cols_row_250,250,'b*') hold off %% seed_pixels = [180*ones(numel(fg_cols_row_180),1) fg_cols_row_180']; bw3b = imfill(bw3a,seed_pixels,conn); bw3c = bw3b & ~bw3a; imshow(bw3c) %% % And rows 180 and 250 are connected. connected = any(bw3c(250,:)) %% % Next time I plan to take another look at this problem using MATLAB % |graph| operations. ##### SOURCE END ##### e5b92f70a47a4b55aeb3134cd0c05804 -->

Categories: Blogs

Read: “Communist Party”: the first chapter of Walkaway

Cory Doctorow - 2017, March 20 - 06:22

There’s still time to pre-order your signed first-edition hardcover of Walkaway, my novel which comes out on April 25 (US/UK), and while you’re waiting for that to ship, here’s chapter one of the novel, “Communist Party” (this is read by Wil Wheaton on the audiobook, where he is joined by such readers as Amanda Palmer and Amber Benson!).


1. Communist Party

[i]

Hubert Vernon Rudolph Clayton Irving Wilson Alva Anton Jeff Harley Timothy Curtis Cleveland Cecil Ollie Edmund Eli Wiley Marvin Ellis Espinoza was too old to be at a Communist party. At twenty-seven, he had seven years on the next oldest partier. He felt the demographic void. He wanted to hide behind one of the enormous filthy machines that dotted the floor of the derelict factory. Anything to escape the frank, flat looks from the beautiful children of every shade and size who couldn’t understand why an old man was creepering around.

“Let’s go,” he said to Seth, who’d dragged him to the party. Seth was terrified of aging out of the beautiful children demographic and entering the world of non-work. He had an instinct for finding the most outré, cutting edge, transgressive goings-on among the children who’d been receding in their rearview mirrors. Hubert, Etc, Espinoza only hung out with Seth because part of his thing about not letting go of his childhood was also not letting go of childhood friends. He was insistent on the subject, and Hubert, Etc was a pushover.

“This is about to get real,” Seth said. “Why don’t you get us beers?”

That was exactly what Hubert, Etc didn’t want to do. The beer was where the most insouciant adolescents congregated, merry and weird as tropical fishes. Each more elfin and tragic than the last. Hubert, Etc remembered that age, the certainty that the world was so broken that only an idiot would deign to acknowledge it or its inevitability. Hubert, Etc often confronted his reflection in his bathroom screen, stared into his eyes in their nest of bruisey bags, and remembered being someone who spent every minute denying the world’s legitimacy, and now he was enmeshed in it. Hubert, Etc couldn’t self-delude the knowledge away. Anyone under twenty would spot it in a second.

“Go on, man, come on. I got you into this party. Least you can do.”

Hubert, Etc didn’t say any obvious things about not wanting to come in the first place and not wanting beer in the second place. There were lots of pointless places an argument with Seth could go. He had his Peter Pan face on, prepared to be ha-ha-only-serious until you wore down, and Hubert, Etc started the night worn.

Walkaway: “Comunist Party”

[Cory Doctorow/Tor.com]

Categories: Blogs

Here’s the schedule for my 25-city US-Canada Walkaway tour!

Cory Doctorow - 2017, March 20 - 06:17

There’s 25 stops in all on the US/Canada tour for WALKAWAY, my next novel, an “optimistic disaster novel” that comes out on April 25 (more stops coming soon, as well as publication of my UK tour).


I’ll be joined in various cities by many worthies, from Neal Stephenson (Seattle) to Ed Snowden (New York) to John Scalzi (LA, Santa Cruz, and San Francisco); Amber Benson (LA); Amie Stepanovich (DC); Joi Ito (Cambridge, MA); Max Temkin (Chicago); Brian David Johnson (Phoenix); Andy Baio (Portland, OR) — and more to come!

I hope to see you there, too!

Join Cory Doctorow on His Walkaway Tour, Starting April 25

[Tor.com]

Categories: Blogs

Fair trade ebooks: how authors could double their royalties without costing their publishers a cent

Cory Doctorow - 2017, March 16 - 05:28


My latest Publishers Weekly column announces the launch-date for my long-planned “Shut Up and Take My Money” ebook platform, which allows traditionally published authors to serve as retailers for their publishers, selling their ebooks direct to their fans and pocketing the 30% that Amazon would usually take, as well as the 25% the publisher gives back to them later in royalties.


I’ll be launching the platform with my next novel, Walkaway, in late April, and gradually rolling out additional features, including a name-your-price system inspired by the Humble Bundle and the Ubuntu payment screen.


Selling your own ebooks means that you can have more than one publisher — say, a UK and a US one — and sell on behalf of both of them, meaning that readers anywhere in the world come to one site to buy their books, and the author takes care of figuring out which publisher gets the payment from that purchase.


It’s all an idea whose time has come! My UK publisher, Head of Zeus, is just launched a very similar initiative for authors who don’t want to host their own stores: BookGrail.


Buying an e-book from a website and sideloading it onto your Kindle will never be as easy as buying it from the Kindle store (though if the world’s governments would take the eminently sensible step of legalizing jailbreaking, someone could develop a product that let Kindles easily access third-party stores on the obvious grounds that if you buy a Kindle, you still have the right to decide whose books you’ll read on it, otherwise you don’t really own that Kindle). But a bookstore operated by an author has an advantage no giant tech platform can offer: a chance to buy your e-books in a way that directly, manifestly benefits the author.

As an author, being my own e-book retailer gets me a lot. It gets me money: once I take the normal 30 percent retail share off the top, and the customary 25 percent royalty from my publisher on the back-end, my royalty is effectively doubled. It gives me a simple, fair way to cut all the other parts of the value-chain in on my success: because this is a regular retail sale, my publishers get their regular share, likewise my agents. And, it gets me up-to-the-second data about who’s buying my books and where.

It also gets me a new audience that no retailer or publisher is targeting: the English-speaking reader outside of the Anglosphere. Travel in Schengen, for example, and you will quickly learn that there are tens of millions of people who speak English as a second (or third, or fourth) language, and nevertheless speak it better than you ever will. Yet there is no reliable way for these English-preferring readers, who value the writer’s original words, unfiltered by translation, to source legal e-books in English.

Amazon and its competitors typically refuse outright to deal with these customers, unable to determine which publisher has the right to sell to them. Most publishing contracts declare these nominally non-English-speaking places to be “open territory” where in theory all of the book’s publishers may compete, but in practice, none of them do.


London Book Fair 2017: Cory Doctorow Unveils His Latest Publishing Experiment—Fair Trade E-Books

[Cory Doctorow/Publishers Weekly]

Categories: Blogs

Preorder my novel Walkaway and get a pocket multitool

Cory Doctorow - 2017, March 15 - 10:29

Tor has produced a multitool to commemorate my forthcoming novel Walkaway, and if you pre-order the book, they’ll send you one! Protip: pre-order from Barnes and Noble and you’ll get a signed copy!


The book has received some humblingly great early notices:

Edward Snowden: Is Doctorow’s fictional Utopia bravely idealistic or bitterly ironic? The answer is in our own hands. A dystopian future is in no way inevitable; Walkaway reminds us that the world we choose to build is the one we’ll inhabit. Technology empowers both the powerful and the powerless, and if we want a world with more liberty and less control, we’re going to have to fight for it.

William Gibson: The darker the hour, the better the moment for a rigorously-imagined utopian fiction. Walkaway is now the best contemporary example I know of, its utopia glimpsed after fascinatingly-extrapolated revolutionary struggle. A wonderful novel: everything we’ve come to expect from Cory Doctorow and more.

Kim Stanley Robinson: Cory Doctorow is one of our most important science fiction writers, because he’s also a public intellectual in the old style: he brings the news and explains it, making clearer the confusions of our wild current moment. His fiction is always the heart of his work, and this is his best book yet, describing vividly the revolutionary beginnings of a new way of being. In a world full of easy dystopias, he writes the hard utopia, and what do you know, his utopia is both more thought-provoking and more fun.

Neal Stephenson: Cory Doctorow has authored the Bhagavad Gita of hacker/maker/burner/open source/git/gnu/wiki/99%/adjunct faculty/Anonymous/shareware/thingiverse/cypherpunk/LGTBQIA*/squatter/upcycling culture and zipped it down into a pretty damned tight techno-thriller with a lot of sex in it.

Yochai Benkler: A beautifully-done utopia, just far enough off normal to be science fiction, and just near enough to the near-plausible, on both the utopian and dystopian elements, to be almost programmatic…a sheer delight.

Kirkus Review: A truly visionary techno-thriller that not only depicts how we might live tomorrow, but asks why we don’t already.

Categories: Blogs

NMR in XXI Century: 30 selected things to do and explore

NMR blog - 2017, March 15 - 05:00

A technologist's view of the many open roads to innovate MR.

Categories: Blogs

Thorarin Bjarnason committed [r165]

AnalyzeNNLS - 2017, March 8 - 18:58

Modified PAR/REC file handling to accommodate V...

Categories: Blogs

Logical indexing

Matlab Image processing blog - 2017, March 7 - 14:01

One of my favorite aspects of MATLAB for image processing is how I can use a binary image to index directly into a grayscale image. The technique is called logical indexing, and I'm going to show you how it works today.

Note: this is an update of a post I originally wrote in 2008.

Let me start with a small example. (As regular readers know, I like to use magic squares for small matrix examples.)

A = magic(5) A = 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9

Every MATLAB user is familiar with ordinary matrix indexing notation.

A(2,3) ans = 7

A(2,3) extracts the 2nd row, 3rd column of the matrix A. You can extract more than one row and column at the same time:

A(2:4, 3:5) ans = 7 14 16 13 20 22 19 21 3

When an indexing expression appears on the left-hand side of the equals sign, that's an assigment. You are changing one or more of the values of the variable on the left-hand side.

A(5,5) = 100 A = 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 100

Here is a frequently-asked MATLAB question: How do I replace all the NaNs in my matrix B with 0s?

An experienced MATLAB user will immediately answer:

B(isnan(B)) = 0;

For example:

B = rand(3,3); B(2, 2:3) = NaN B = 0.2217 0.3188 0.0855 0.1174 NaN NaN 0.2967 0.5079 0.8010

Replace the NaNs with zeros:

B(isnan(B)) = 0 B = 0.2217 0.3188 0.0855 0.1174 0 0 0.2967 0.5079 0.8010

The expression B(isnan(B)) is an example of logical indexing. Logical indexing is a compact and expressive notation that's very useful for many image processing operations.

Let's talk about the basic rules of logical indexing, and then we'll reexamine the expression B(isnan(B)).

If C and D are matrices, then C(D) is a logical indexing expression if D is a logical matrix.

Logical is one of the fundamental data types for MATLAB arrays. Relational operators, such as == or >, produce logical arrays automatically.

C = hilb(4) C = 1.0000 0.5000 0.3333 0.2500 0.5000 0.3333 0.2500 0.2000 0.3333 0.2500 0.2000 0.1667 0.2500 0.2000 0.1667 0.1429 D = C > 0.4 D = 4×4 logical array 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0

If we use D as an index into C with the expression C(D), then we will extract all the values of C corresponding to nonzero values of D and returns them as a column vector. It is equivalent to C(find(D)).

C(D) ans = 1.0000 0.5000 0.5000

Now we know enough to break down the B(isnan(B)) expression to see how it works.

B = rand(3,3); B(2, 2:3) = NaN; nan_locations = isnan(B) nan_locations = 3×3 logical array 0 0 0 0 1 1 0 0 0 B(nan_locations) ans = NaN NaN B(nan_locations) = 0 B = 0.0292 0.4886 0.4588 0.9289 0 0 0.7303 0.2373 0.5468

Functions in the Image Processing Toolbox, as well as the MATLAB functions imread and imwrite, follow the convention that logical matrices are treated as binary (black and white) images. For example, when you read a 1-bit image file using imread, it returns a logical matrix:

bw = imread('text.png'); whos bw Name Size Bytes Class Attributes bw 256x256 65536 logical

This convention, together with logical indexing, makes it very convenient and expressive to use binary images as pixel masks for extracting or operating on sets of pixels.

Here's an example showing how to use logical indexing to compute the histogram of a subset of image pixels. Specifically, given a grayscale image and a binary segmentation, compute the histogram of just the foreground pixels in the image.

Here's our original image:

I = imread('rice.png'); imshow(I)

Here's a segmentation result (computed and saved earlier), represented as a binary image:

url = 'http://blogs.mathworks.com/images/steve/192/rice_bw.png'; bw = imread(url); imshow(bw)

Now use the segmentation result as a logical index into the original image to extract the foreground pixel values.

foreground_pixels = I(bw); whos foreground_pixels Name Size Bytes Class Attributes foreground_pixels 17597x1 17597 uint8

Finally, compute the histogram of the foreground pixels.

figure imhist(foreground_pixels)

As another example, you could complement the binary image to compute something based on the background pixels.

imhist(I(~bw))

PS. I expect that this will be the last blog post that I write using R2016b. Keep an eye on the downloads page!

\n'); d.write(code_string); // Add copyright line at the bottom if specified. if (copyright.length > 0) { d.writeln(''); d.writeln('%%'); if (copyright.length > 0) { d.writeln('% _' + copyright + '_'); } } d.write('\n'); d.title = title + ' (MATLAB code)'; d.close(); } -->


Get the MATLAB code (requires JavaScript)

Published with MATLAB® R2016b

_. % % Let me start with a small example. (As regular readers know, I like % to use magic squares for small matrix examples.) A = magic(5) %% % Every MATLAB user is familiar with ordinary matrix indexing % notation. A(2,3) %% % |A(2,3)| extracts the 2nd row, 3rd column of the matrix |A|. You % can extract more than one row and column at the same time: A(2:4, 3:5) %% % When an indexing expression appears on the left-hand side of % the equals sign, that's an assigment. You are changing one or more of the % values of the variable on the left-hand side. A(5,5) = 100 %% % Here is a frequently-asked MATLAB question: _How do I replace all the % NaNs in my matrix B with 0s?_ % % An experienced MATLAB user will immediately answer: % % B(isnan(B)) = 0; % % For example: B = rand(3,3); B(2, 2:3) = NaN %% % Replace the NaNs with zeros: B(isnan(B)) = 0 %% % The expression |B(isnan(B))| is an example of _logical indexing_. % Logical indexing is a compact and expressive notation that's very useful % for many image processing operations. % % Let's talk about the basic rules of logical indexing, and then % we'll reexamine the expression |B(isnan(B))|. % % If |C| and |D| are matrices, then |C(D)| is a logical indexing % expression if |D| is a _logical_ matrix. % % _Logical_ is one of the fundamental data types for MATLAB arrays. % Relational operators, such as |==| or |>|, produce logical % arrays automatically. C = hilb(4) %% D = C > 0.4 %% % If we use |D| as an index into |C| with the expression |C(D)|, then we % will extract all the values of |C| corresponding to nonzero values of |D| % and returns them as a column vector. It is equivalent to |C(find(D))|. C(D) %% % Now we know enough to break down the |B(isnan(B))| expression to see % how it works. B = rand(3,3); B(2, 2:3) = NaN; nan_locations = isnan(B) %% B(nan_locations) %% B(nan_locations) = 0 %% % Functions in the Image Processing Toolbox, as well as the % MATLAB functions |imread| and |imwrite|, follow the convention that % logical matrices are treated as binary (black and white) % images. For example, when you read a 1-bit image file using % |imread|, it returns a logical matrix: bw = imread('text.png'); whos bw %% % This convention, together with logical indexing, makes it very % convenient and expressive to use binary images as pixel masks % for extracting or operating on sets of pixels. %% % Here's an example showing how to use logical indexing to % compute the histogram of a subset of image pixels. % Specifically, given a grayscale image and a binary % segmentation, compute the histogram of just the foreground % pixels in the image. % % Here's our original image: I = imread('rice.png'); imshow(I) %% % Here's a segmentation result (computed and saved earlier), % represented as a binary image: url = 'http://blogs.mathworks.com/images/steve/192/rice_bw.png'; bw = imread(url); imshow(bw) %% % Now use the segmentation result as a logical index into the % original image to extract the foreground pixel values. foreground_pixels = I(bw); whos foreground_pixels %% % Finally, compute the histogram of the foreground pixels. figure imhist(foreground_pixels) %% % As another example, you could complement the binary image to compute % something based on the background pixels. imhist(I(~bw)) %% % _PS. I expect that this will be the last blog post that I write using % R2016b. Keep an eye on the _ ##### SOURCE END ##### e286582d3ff74f9f8ff5c3de3b9c3809 -->

Categories: Blogs

Fill Your Boots: my column on how technology could let us work like artisans and live like kings

Cory Doctorow - 2017, March 3 - 06:39

My latest Locus column is “Fill Your Boots,” in which I talk about how scientists, sf writers, economists and environmental activists have wrestled with the question of abundance — how the “green left” transformed left wing politics from the promise of every peasant living like a lord to the promise of every lord living like a peasant.


One thing everyone can agree on is that market competition and technology has made material abundance a lot less material: the labor, energy, and resources in a car, a house, or a shirt are a mere fraction of what they were a couple of generations ago, and continue to fall with no end in sight. Another point of commonality is that computers make it easier to coordinate your work with other people, whether that’s Github providing the scaffold for building out an open source project or Slack giving people scattered all over the world the power to plan a product launch or a birthday party.

The combination of reduced material inputs to goods and cheap coordination presents us with the possibility of a new, better kind of abundance: a world where we leave behind the demands of the assembly line and the anxiety of whether the light-switch will always turn on the lights, for one where we treat sunny days a jubilees, when we can use as much unbankable and infinite solar energy as we want, leaving the doors open and the air conditioners running. It’s the best of both worlds, freeing work from the tyranny of other peoples’ schedules without giving up the fantastic comforts of material abundance.

The limits to labor/energy/material efficiency are speculative. We don’t know what the hard limits are on how little material can go into a car, how little fuel can propel an airplane, or how much of the labor embodied in your house could be performed by robots.

We don’t need to speculate to understand how sweet our lives could be if they were re-tuned to the rhythms of the natural world, if every time the sun shone we stopped having to worry about closing the door, if every time it rained we stopped worrying about whether the toilet really needs flushing, or whether it can mellow for one more yellow.

My next novel, Walkaway, includes an entire subculture called ‘‘the bumblers.’’ These are the survivors of a speculative investment bubble in zeppelins, a global phenomenon that left millions around the world with the knowledge and capacity to build airships, and networks of friends, fellow travellers, and potential couch-surfing hosts all over the world. These sky-hobos go aloft in their minimally steerable zeppelins and literally go wherever the wind blows them, knowing that they will almost certainly meet someone interesting, wherever the zeppelin happens to take them. It’s not jet travel. You can’t decide where you’re going. But if you don’t care where you end up – because all you want is to get somewhere – then bumbling is superior to conventional aviation on every metric.

Here is where the green left and the bright green left can meet: using bright green, high tech coordina­tion tools, we can restore the pastoral green, artisanal autonomy that privileges mindful play over mindless work. The motto of Magpie Killjoy’s Steampunk zine was ‘‘love the machine, hate the factory.’’ Love the dividends of coordinated labor, hate the loss of freedom we suffer when we have to coordinate with others. Have your cake and eat it too.

The Jubilee: Fill Your Boots [Cory Doctorow/Locus Magazine]

Categories: Blogs

Reply All covers DRM and the W3C

Cory Doctorow - 2017, March 2 - 07:45

In the latest episode of Reply All, a fantastic tech podcast, the hosts and producers discuss the situation with DRM, the future of the web, and the W3C — a piece I’ve been working on them with for a year now.


The issue is a complicated and eye-glazingly technical one, and they do a genuinely excellent job presenting the story. Inevitably, there’s some nuance lost in the translation, and so here’s a bit more, for people who are interested.

The story talks about DRM as an anti-piracy technology. I think that’s just wrong, though DRM advocates walk a confusing line on this question. They freely admit that DRM can be broken by skilled attackers, and that dishonest people can just access versions of movies or songs or whatever that the DRM-breakers have stripped the DRM off of (the Reply All host starts off by describing how he hits all kinds of problems with DRM on movies he pays for, leading him to download easy-to-find cracked versions).

So if DRM isn’t anti-piracy, what is it? DRM isn’t really a technology at all, it’s a law. Specifically, it’s section 1201 of the US DMCA (and its international equivalents). Under this law, breaking DRM is a crime with serious consequences (5 years in prison and a $500,000 fine for a first offense), even if you’re doing something that would otherwise be legal. This lets companies treat their commercial strategies as legal obligations: Netflix doesn’t have the legal right to stop you from recording a show to watch later, but they can add DRM that makes it impossible to do so without falling afoul of DMCA.

This is the key: DRM makes it possible for companies to ban all unauthorized conduct, even when we’re talking about using your own property in legal ways. This intrudes on your life in three ways:

1. It lets companies sue and threaten security researchers who find defects in products

2. It lets companies sue and threaten accessibility workers who adapt technology for use by disabled people

3. It lets companies sue and threaten competitors who want to let you do more with your property — get it repaired by independent technicians, buy third-party parts and consumables, or use it in ways that the manufacturer just doesn’t like.

How do we know that companies only want DRM because they want to abuse this law, and not because they want to fight piracy? Because they told us so. At the W3C, we proposed a compromise: companies who participate at W3C would be allowed to use it to make DRM, but would have to promise not to invoke the DMCA in these ways that have nothing to do with piracy. So far, nearly 50 W3C members — everyone from Ethereum to Brave to the Royal National Institute for Bind People to Lawrence Berkeley National Labs — have endorsed this, and all the DRM-supporting members have rejected it.

In effect, these members are saying, “We understand that DRM isn’t very useful for stopping piracy, but that law that lets us sue people who aren’t breaking copyright law? Don’t take that away!”

The Director of the W3C, web inventor Tim Berners-Lee, wrote recently about why he supports DRM standardization, an odd step that it hard to understand, really: the leaders of the DRM standardization committee at the W3C have asked Berners-Lee to consult with his members to ask whether they want to see this DRM standard published. Instead, he appears to be telling us what decision he plans on coming to, regardless of how that consultation goes.

#90 Matt Lieber Goes To Dinner [Reply All/Gimlet]

Categories: Blogs

Coming to DC on March 6: a panel on right to repair, DRM, and property rights in the digital age

Cory Doctorow - 2017, March 1 - 06:09

On Monday, March 6 at 10AM, I’ll be participating in a non-partisan R-Street event on “Property Rights in the Digital Age,” with participants from the Heritage Foundation, R-Street, the Open Technology Institute, and Freedomworks: “As we enter an age near total connectivity, we must ask ourselves, are our laws keeping up with technology? Do we need to rewrite the rules to preserve our traditional notions of property, or embrace the brave new world of licensing everything?” (RSVP)

Categories: Blogs

New Yorkers! Come see Edward Snowden and me onstage at the NYPL on the Walkaway tour!

Cory Doctorow - 2017, February 26 - 12:07

I’m touring 20 US cities (plus dates in Canada and the UK!) with my forthcoming novel Walkaway; the full tour hasn’t been announced yet, but I’m delighted to reveal that the NYC stop on May 3 will be at the New York Public Library, where my interlocutor will be the whistleblower Edward Snowden. Tickets are $10-25! (Reminder: there are also signed first-edition hardcovers available for pre-order in the USA and UK).

Categories: Blogs

Now in the UK! Pre-order signed copies of the first edition hardcover of Walkaway, my first adult novel since Makers

Cory Doctorow - 2017, February 11 - 10:22

The UK’s Forbidden Planet is now offering signed hardcovers of Walkaway, my first novel for adults since 2009 — this is in addition to the signed US hardcovers being sold by Barnes and Noble.

Walkaway has scored starred reviews in Booklist (“memorable and engaging” and “ultimately suffused with hope”) and Kirkus (“A truly visionary techno-thriller that not only depicts how we might live tomorrow, but asks why we don’t already”).

Edward Snowden said the book was “a reminder that the world we choose to build is the one we’ll inhabit” and Kim Stanley Robinson called it “a utopia both more thought-provoking and more fun than a dystopia” and Neal Stephenson called “the Bhagavad Gita of hacker/maker/ burner/open source/git/gnu/wiki/99%/adjunct faculty/Anonymous/shareware/thingiverse/cypherpunk/ LGTBQIA*/squatter/upcycling culture, zipped down into a pretty damned tight techno-thriller with a lot of sex in it.” Yochai Benkler said “A beautifully-done utopia, just far enough off normal to be science
fiction, and just near enough to the near-plausible, on both the
utopian and dystopian elements, to be eerie as almost programmatic…a
sheer delight.”

The book comes out on April 25; I’m touring 20 cities in the USA, plus major Canadian cities and a week-long tour of the UK — details TBA.

Pre-order signed Walkaway in the UK [Forbidden Planet]

Pre-order signed Walkaway in the USA [Barnes and Noble]

Categories: Blogs

Pre-order a signed first edition of Walkaway, which got a starred review in Booklist today!

Cory Doctorow - 2017, February 1 - 14:08

Here’s a reminder that you can pre-order a signed first edition hardcover of Walkaway, my first novel for adults since 2009, which William Gibson called “A wonderful novel” and Edward Snowden called “a reminder that the world we choose to build is the one we’ll inhabit” and Kim Stanley Robinson called “a utopia is both more thought-provoking and more fun than a dystopia” and Neal Stephenson called “the Bhagavad Gita of hacker/maker/burner/open source/git/gnu/wiki/99%/adjunct faculty/Anonymous/shareware/thingiverse/cypherpunk/LGTBQIA*/squatter/upcycling culture, zipped down into a pretty damned tight techno-thriller with a lot of sex in it.”


I signed 2,900 early copies of the first edition, and I’ll be visiting 20 US cities as well as cities across Canada and the UK this spring to read from and discuss the book.

Happily, today’s Booklist contained a starred review by Regina Schroeder, who called it “memorable and engaging” and “ultimately suffused with hope.” This is the book’s second starred review — last December’s Kirkus reviews called it “A truly visionary techno-thriller that not only depicts how we might live tomorrow, but asks why we don’t already.”


The book drops on April 25, and I’m so damned excited I can barely contain myself!

Order your signed copy here.

Categories: Blogs

The cover of this week’s Bookseller!

Cory Doctorow - 2017, January 31 - 07:56

Categories: Blogs