Posted by
Jon Harman-3 on
Apr 25, 2008; 8:19pm
URL: http://imagej.273.s1.nabble.com/macro-to-read-Canon-viewport-data-tp3696425.html
Hi,
I have been having a great deal of fun with my new Canon A720IS. Fun
mainly because of CHDK. CHDK is a "firmware add-on for Canon's Digic II
& Digic III cameras":
http://chdk.wikia.com/wiki/CHDKBuilding on CHDK's code I wrote a routine to save the viewport data from
the camera. The viewport is the image data that appears on the LCD
screen. It is encoded in a YUV format. See my post on the CHDK forum
for more info:
http://chdk.setepontos.com/index.php/topic,1171.0.htmlFor CHDK developers I have written an ImageJ macro to display the
viewport data. Thanks to Curtis it is now finished. Here it is:
//This macro can read Canon viewport data and convert to RGB format.
//For my camera, the A720IS, the viewport data is 360x240 x 3bytes.
//Every 6 bytes in the data is encoded as U,Y1,V,Y2,Y3,Y4 in the YUV
color system.
//This routine decodes that into 4 RGB pixels. So the output for my
camera is
//720x280. The true aspect ratio is 360x240.
path = File.openDialog("Choose a File");
run("Raw...", "open=["+path+"] image=[24-bit RGB] width=360 height=240
offset=0 number=1 gap=0 little-endian");
setBatchMode(true);
id0 = getImageID();
width = getWidth();
height = getHeight();
line = newArray(width * 2);
newImage("Converted", "RGB", width * 2, height, 1);
id1 = getImageID();
for (h=0;h<height;h++) {
w1 = 0;
selectImage(id0);
for(w=0;w<width;w+=2) {
p = getPixel(w,h);
u = (p>>16)&0xff;
if ((u&0x80) != 0) u = u - 255 + 1;
y = (p>>8)&0xff;
v = p &0xff;
if ((v&0x80) != 0) v = 255-v + 1;
r = clip(((y * 4096) + v*5743 + 2048)/4096); // R
g = clip(((y * 4096) - u*1411 - v*2925 + 2048)/4096); // G
b = clip(((y * 4096) + u*7258 + 2048)/4096); // B
line[w1++] = (r << 16) + (g << 8) + b;
p = getPixel(w+1,h);
y = (p>>16) & 0xff;
y1 = (p>>8) & 0xff;
y2 = p & 0xff;
r = clip(((y1 * 4096) + v*5743 + 2048)/4096); // R
g = clip(((y1 * 4096) - u*1411 - v*2925 + 2048)/4096); // G
b = clip(((y1 * 4096) + u*7258 + 2048)/4096); // B
line[w1++] = (r << 16) + (g << 8) + b;
r = clip(((y1 * 4096) + v*5743 + 2048)/4096); // R
g = clip(((y1 * 4096) - u*1411 - v*2925 + 2048)/4096); // G
b = clip(((y1 * 4096) + u*7258 + 2048)/4096); // B
line[w1++] = (r << 16) + (g << 8) + b;
r = clip(((y2 * 4096) + v*5743 + 2048)/4096); // R
g = clip(((y2 * 4096) - u*1411 - v*2925 + 2048)/4096); // G
b = clip(((y2 * 4096) + u*7258 + 2048)/4096); // B
line[w1++] = (r << 16) + (g << 8) + b;
}
selectImage(id1);
for(w=0;w<width * 2; w++) setPixel(w,h,line[w]);
}
setBatchMode(false);
function clip(a) {
if(a < 0) a = 0;
if(a > 255) a = 255;
return a;
}