Page 1 of 1

Avoiding multiple reads with txt:- and clone?

Posted: 2015-08-06T10:55:20-07:00
by aporthog
I'm trying to do some operations on CR2 files and then read the results with txt:- Previously I just did these commands one by one, rereading the CR2 file each time. I was wondering if I can avoid the multiple reads and somehow repeat the txt:-, perhaps in a clone operation. (This is all on the command line - I know this can be avoided using a language binding like PerlMagick but I'm constrained to the command line for this). The operations are done in a perl program and the output is captured and analyzed.

I tried this as an example but it just sat there and never ended (both clones do the same thing but this is just a test):

Code: Select all

convert "file.CR2" -depth 8 ( -clone 0 -resize 30x30^ -type Grayscale -depth 8 txt:- ) ( -clone 1 -resize 30x30^ -type Grayscale -depth 8 txt:- )
If there isn't a way to do it I'll generate a small grayscale version of the CR2 and do the multiple reads on that, which will work for what I want to do. But temp files are ugly and I was wondering if there is a more elegant way.

ImageMagick-6.8.9-Q8
Windows 7

Arvin

PS. On a tangent, the CR2 files are 16-bit and I put that first -depth 8 there because I thought I read someplace it would speed up the read.

Re: Avoiding multiple reads with txt:- and clone?

Posted: 2015-08-06T11:43:52-07:00
by snibgo
For clarity, I split it into lines. Use whatever line-continuation characters your script language needs.

Code: Select all

convert
  "file.CR2"
  -depth 8
  ( -clone 0 -resize 30x30^ -type Grayscale -depth 8 txt:- )
  ( -clone 1 -resize 30x30^ -type Grayscale -depth 8 txt:- )
There is no output file, so the syntax is invalid. You can throw output away with NULL:

Code: Select all

convert
  "file.CR2"
  -depth 8
  ( -clone 0 -resize 30x30^ -type Grayscale -depth 8 txt:- )
  ( -clone 1 -resize 30x30^ -type Grayscale -depth 8 txt:- )
  NULL:
I don't understand what you are trying to do. Reading the CR2 file makes an image. You clone this, resize etc, then read text input. It waits for you to type it in. Did you mean to write text output?

Code: Select all

convert
  "file.CR2"
  -depth 8
  ( -clone 0 -resize 30x30^ -type Grayscale -depth 8 +write txt:- )
  ( -clone 1 -resize 30x30^ -type Grayscale -depth 8 +write txt:- )
  NULL:
After the first "write txt", you have two images in the list, numbered 0 and 1. So "-clone 1" makes a copy of the second image, which is already resized. Maybe you want to clone image 0 again. But why do exactly the same operation twice?

Perhaps you want to resize etc, and write the result twice. Then you don't need to clone. Just write however many times you want.

Code: Select all

convert
  "file.CR2"
  -depth 8
  -resize 30x30^ -type Grayscale -depth 8
  +write txt:-
  +write txt:-
  NULL:
"-depth 8" won't speed up the read. It only affects the output.

Re: Avoiding multiple reads with txt:- and clone?

Posted: 2015-08-06T12:10:05-07:00
by aporthog
Sorry for not being clear. This works exactly perfectly. I needed the +write and the NULL: Also you're right: I wanted to perform a different operation on the original image, not take the output of the first operation as the input of the second (though in my example I just did the same operation for testing - I really intend to do something different each time).

It's all output into a single stream of text delimited by the string "# ImageMagick pixel enumeration" so I can tell which chunk applies to which operation when I analyze the output in my perl program.

I think I can speed things up by creating that temp version in the first clone then doing the additional operations on that. Thanks for pointing out my confusion with the clone numbers. I think this is what I ultimately want to do:

Code: Select all

convert
  "file.CR2"
  ( -clone 0 -resize 200x200! -type Grayscale -depth 8 )
  ( -clone 1 -resize 200x1! +write txt:- )
  ( -clone 1 -resize 1x200! +write txt:- )
  NULL:
I'm just analyzing pixels and getting the average brightness in gray values across the height and width of the image. Looking for different patterns etc. I don't need to analyze the millions of pixels in the original. It's good enough to let IM do the heavy lifting of averaging values in the resize and look at a smaller version then multiply the results by the scaling factor at the end to apply them to the original image.

Anyway, I'm on my way again. Thanks!

Arvin

Re: Avoiding multiple reads with txt:- and clone?

Posted: 2015-08-06T13:52:11-07:00
by aporthog
OK, I assembled my final command which lets me look at average brightness at different parts of the image. I was reading a bit more on IM file handling and basic usage and added -type Grayscale and a resize appended to the filename in brackets to maybe speed things up. It works perfectly but it's very very slow. I'm wondering if I'm doing something wrong. I want it to make a 10% scaled version of the original in grayscale and then operate only on that in subsequent clone operations:

Code: Select all

convert 
  -type Grayscale 
  "file.CR2[562x374]"
  ( -clone 0 -rotate 270 -level 10% -normalize  )
  ( -clone 1 -resize 1x562! +write txt:- )
  ( -clone 1 -resize 374x1! +write txt:- )
  ( -clone 1 -crop 374x40x0x0 -resize 374x1! +write txt:- )
  ( -clone 1 -crop 374x40x0x523 -resize 374x1! +write txt:- )
  NULL:
I've done a lot of this sort of analysis with IM in the past but speed was never an issue so I just did it by reading the CR2 multiple times. Now speed has become an issue. The last two clones I added that examine the top and bottom 40 pixels of the image seem to be the things that suddenly made it slow.

Arvin

Re: Avoiding multiple reads with txt:- and clone?

Posted: 2015-08-06T14:31:07-07:00
by fmw42
rather than writing to txt:, you may want to just write out the image mean. you can do that with

Code: Select all

-format "%[mean]" +write info: 
or

Code: Select all

-format "%[fx:mean]" +write info: 
in place of

Code: Select all

+write txt:
[mean} will show you the mean in the range of 0 to quantumrange (0-255 for Q8 and 0-65535 for Q16)

[fx:mean] will show the mean in the range 0 to 1


See http://www.imagemagick.org/script/escape.php

Re: Avoiding multiple reads with txt:- and clone?

Posted: 2015-08-06T14:44:14-07:00
by aporthog
I take it back that it's working correctly. Looking at the output I just noticed I'm getting 32 blocks of text instead of the 4 blocks I was expecting. When I just do this:

Code: Select all

convert 
  -type Grayscale 
  "file.CR2[562x374]"
  ( -clone 0 -rotate 270 -level 10% -normalize  )
  ( -clone 1 -resize 1x562! +write txt:- )
  ( -clone 1 -resize 374x1! +write txt:- )
  NULL:
I get two blocks of text - one per +write - and it's pretty fast. But when I do this (on edit: corrected a copy/paste error):

Code: Select all

convert
  -type Grayscale
  "file.CR2[562x374]"
  ( -clone 0 -rotate 270 -level 10% -normalize  )
  ( -clone 1 -resize 1x562! +write txt:- )
  ( -clone 1 -resize 374x1! +write txt:- )
  ( -clone 1 -crop 374x40x0x0 -resize 374x1! +write txt:- )
  ( -clone 1 -crop 374x40x0x523 -resize 374x1! +write txt:- )
  NULL:
I get 32 blocks of text and it's very slow. I think I'm not understanding clone.

Re: Avoiding multiple reads with txt:- and clone?

Posted: 2015-08-06T14:46:14-07:00
by fmw42
-rotate 270 -level 10% -normalize )
The paren at the end is unmatched. Remove it.

convert
"file.CR2"
-rotate 270 -level 10% -normalize )
( -clone 1 -resize 1x562! +write txt:- )
( -clone 1 -resize 374x1! +write txt:- )
( -clone 1 -crop 374x40x0x0 -resize 374x1! +write txt:- )
( -clone 1 -crop 374x40x0x523 -resize 374x1! +write txt:- )
NULL:
There is no clone 1, Clones start with 0 as the first image in the sequence. Perhaps you mean all -clone 1 to be -clone 0.

You also must add line ending characters if each of these lines is on a new line. On Windows that is ^.

If on unix, you must use \ for the line ends and also escape the parens as \( and \)

Snibgo can clarify further if he sees more to add or correct.

Re: Avoiding multiple reads with txt:- and clone?

Posted: 2015-08-06T14:51:12-07:00
by aporthog
You caught it before I had a chance to correct it! I made a copy and paste error and the actual command I used is above.

Re: Avoiding multiple reads with txt:- and clone?

Posted: 2015-08-06T15:42:28-07:00
by snibgo

Re: Avoiding multiple reads with txt:- and clone?

Posted: 2015-08-07T08:40:24-07:00
by aporthog
Hey you're right. Those should be plusses. That was the problem. I can almost see why there were 32 blocks of text now. What a stupid mistake. I've done cropping correctly in IM a zillion times. Thanks for spotting it. It works now and I get just 4 blocks of text and it's pretty speedy. I also see that I don't need that first clone in there so I've simplified it a bit to this:

Code: Select all

convert ^
  -type Grayscale  ^
  "file.CR2[562x374]" ^
  -rotate 270 -level 10% -normalize ^
  ( -clone 0 -resize 1x562! +write txt:- ) ^
  ( -clone 0 -resize 374x1! +write txt:- ) ^
  ( -clone 0 -crop 374x40+0+0 -resize 374x1! +write txt:- ) ^
  ( -clone 0 -crop 374x40+0+523 -resize 374x1! +write txt:- ) ^
  NULL:

Re: Avoiding multiple reads with txt:- and clone?

Posted: 2018-03-22T09:53:10-07:00
by fmw42
You can avoid multiple clones by writing to in-memory mpr: format, though I am not sure you will gain much in processing speed.

Code: Select all

convert ^
  -type Grayscale  ^
  "file.CR2[562x374]" ^
  -rotate 270 -level 10% -normalize ^
  -write mpr:img +delete ^
  ( mpr:img -resize 1x562! +write txt:- ) ^
  ( mpr:img -resize 374x1! +write txt:- ) ^
  ( mpr:img -crop 374x40+0+0 -resize 374x1! +write txt:- ) ^
  ( mpr:img -crop 374x40+0+523 -resize 374x1! +write txt:- ) ^
  NULL: