Adding and retrieving some Meta data to a png Image - c++

I need to add some metadata to a lot of images. For example I need to add the position of the right eye and left eye to the metadata.
That is righteye(291,493), lefteye(453,491) like that. I am working with png files now. Example with gimp is given bleow.
Is there any good way to add these information to image metadata? I have seen keywords and strings in png file. Is that the solution to my problem? Also I need a tool to edit the metadata. I have a lot of facial images, and I need a tool to add these metadata to each image. And also I need to retrieve these data from each image programmatically. Please suggest a proper way to solve all these tasks.

It seems that you can set a comment in a PNG image using either exiv2 or ImageMagick both of which have command-line versions and C++ library bindings.
So, if you do:
# Set image description using "exiv2"
exiv2 -M"add Exif.Image.ImageDescription Ascii 'left eye (200,201) right eye(202,203)'" image.png
# Set image comment usimg "ImageMagick"
convert -comment "left eye(76,77) right eye(78,79)" image.png image.png
You can now look at the result with exiftool
exiftool image.png
ExifTool Version Number : 10.00
File Name : image.png
Directory : .
File Size : 496 bytes
File Modification Date/Time : 2015:09:20 20:45:29+01:00
File Access Date/Time : 2015:09:20 20:49:22+01:00
File Inode Change Date/Time : 2015:09:20 20:45:29+01:00
File Permissions : rw-r--r--
File Type : PNG
File Type Extension : png
MIME Type : image/png
Image Width : 1
Image Height : 1
Bit Depth : 1
Color Type : Grayscale
Compression : Deflate/Inflate
Filter : Adaptive
Interlace : Noninterlaced
White Point X : 0.3127
White Point Y : 0.329
Red X : 0.64
Red Y : 0.33
Green X : 0.3
Green Y : 0.6
Blue X : 0.15
Blue Y : 0.06
Background Color : 1
Modify Date : 2015:09:20 20:45:29
Exif Byte Order : Little-endian (Intel, II)
Image Description : left eye (200,201) right eye(202,203) <--- HERE
Comment : left eye(76,77) right eye(78,79) <--- HERE
Datecreate : 2015-09-20T20:45:29+01:00
Datemodify : 2015-09-20T20:45:29+01:00
Exif Image Description : left eye (200,201) right eye(202,203)
Image Size : 1x1
Megapixels : 0.000001
or look at the result with ImageMagick's identify command:
identify -verbose image.png
Format: PNG (Portable Network Graphics)
Mime type: image/png
Class: PseudoClass
Geometry: 1x1+0+0
Units: Undefined
Type: Bilevel
Base type: Bilevel
Endianess: Undefined
Colorspace: Gray
Depth: 8/1-bit
Channel depth:
gray: 1-bit
Channel statistics:
Pixels: 1
Gray:
min: 0 (0)
max: 0 (0)
mean: 0 (0)
standard deviation: 0 (0)
kurtosis: 0
skewness: 0
entropy: nan
Colors: 1
Histogram:
1: ( 0, 0, 0) #000000 gray(0)
Colormap entries: 2
Colormap:
0: ( 0, 0, 0) #000000 gray(0)
1: (255,255,255) #FFFFFF gray(255)
Rendering intent: Undefined
Gamma: 0.454545
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: gray(255)
Border color: gray(223)
Matte color: gray(189)
Transparent color: gray(0)
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 1x1+0+0
Dispose: Undefined
Iterations: 0
Compression: Zip
Orientation: Undefined
Properties:
comment: left eye(76,77) right eye(78,79) <--- HERE
date:create: 2015-09-20T20:45:29+01:00
date:modify: 2015-09-20T20:45:29+01:00
exif:ImageDescription: left eye (200,201) right eye(202,203) <--- HERE
png:bKGD: chunk was found (see Background color, above)
png:cHRM: chunk was found (see Chromaticity, above)
png:IHDR.bit-depth-orig: 1
png:IHDR.bit_depth: 1
png:IHDR.color-type-orig: 0
png:IHDR.color_type: 0 (Grayscale)
png:IHDR.interlace_method: 0 (Not interlaced)
png:IHDR.width,height: 1, 1
png:text: 5 tEXt/zTXt/iTXt chunks were found
png:text-encoded profiles: 1 were found
png:tIME: 2015-09-20T20:45:29Z
signature: 709e80c88487a2411e1ee4dfb9f22a861492d20c4765150c0c794abd70f8147c
Profiles:
Profile-exif: 70 bytes
Artifacts:
filename: image.png
verbose: true
Tainted: False
Filesize: 496B
Number pixels: 1
Pixels per second: 1PB
User time: 0.000u
Elapsed time: 0:01.000
Version: ImageMagick 6.9.1-10 Q16 x86_64 2015-09-08 http://www.imagemagick.org
Or using:
exiftool -s -Comment image.png
Comment : left eye(76,77) right eye(78,79)
Or set a comment with exiftooland read with ImageMagick in either of two ways:
exiftool -comment="Crazy Comment" image.png
identify -verbose image.png | grep Crazy
comment: Crazy Comment
identify -format "%[c]" image.png
Crazy Comment

Related

Is it possible to increase resolution of image inserted to Word document from RMarkdown's TikZ?

I have simple RMarkdown document:
---
output:
word_document: default
html_document: default
---
```{r,engine='tikz', fig.ext = 'png'}
\begin{tikzpicture}
\path (0,0) node
(x) {Hello World!}
(3,1) node[circle,draw](y) {$\int_1^2 x \mathrm d x$};
\draw[->,blue]
(x) -- (y);
\draw[->,red]
(x) -| node[near start,below] {label} (y);
\draw[->,orange] (x) .. controls +(up:1cm) and +(left:1cm) .. node[above,sloped] {label} (y);
\end{tikzpicture}
```
It is example from 17.11 of pgfmanual.pdf.
HTML output is great if I change 'png' to 'svg':
It produces circle and rectangle with tikz engine.
But the resulting image looks ugly and pixelated in DOCX even with 100% zoom:
I tried to change fig.width, dpi, out.width but did not get positive results.
The best result for me would me the following: get high resolution image with dimensions as specified in TikZ code.
Is it possible to increase resolution of image inserted to Word document from TikZ?
Update 1 : the proposed solution by #CL with set pandoc's dpi using pandoc_args does not work.
Update 2 : the proposed by #tarleb solution with {r,engine='tikz', engine.opts = list(convert.opts = '-density 800 -resize 800x800'), fig.ext = 'png'}:
---
output:
word_document: default
html_document: default
---
```{r,engine='tikz', engine.opts = list(convert.opts = '-density 800 -resize 800x800'), fig.ext = 'png'}
\begin{tikzpicture}
\path (0,0) node
(x) {Hello World!}
(3,1) node[circle,draw](y) {$\int_1^2 x \mathrm d x$};
\draw[->,blue]
(x) -- (y);
\draw[->,red]
(x) -| node[near start,below] {label} (y);
\draw[->,orange] (x) .. controls +(up:1cm) and +(left:1cm) .. node[above,sloped] {label} (y);
\end{tikzpicture}
```
ends in error:
sh: -density 800 -resize 800x800: command not found
Quitting from lines 8-18 (tikz-sizing.Rmd)
Error in engine(options) :
Failed to compile tikz-sizing_files/figure-docx/unnamed-chunk-1-1.pdf to tikz-sizing_files/figure-docx/unnamed-chunk-1-1.png
Calls: <Anonymous> ... process_group.block -> call_block -> block_exec -> in_dir -> engine
Execution halted
The issue comes from the way TikZ images are created and converted. Knitr first compiles the code into a PDF file via pdflatex (or luatex/XeLaTeX). The resulting PDF is then converted to PNG via ImageMagick's convert. The PDF contains a vector graphic, while PNG is a pixel-oriented bitmap format; quality of the resulting PNG is limited only by the sampling rate used by the converter. The default used by ImageMagick is 72 dpi, cranking it up to a large value (like 300) will give better results for small images.
R Markdown allows to control the PDF → PNG conversion via the engine.opts setting:
{r, engine='tikz', engine.opts = list( convert = 'convert', convert.opts = '-density 300'), fig.ext = 'png'}
This tells ImageMagick to use a higher sampling rate / pixel density. A value like 300 should be enough, higher values will improve image quality at the cost of greater file sizes.

Convert image magick command to magick++ c++ code

I'm working on an image preprocessing project in my university and used an image magick script to clean image background.Now I want to get the same output through Magick++ (c++ api for imageMagick).
ImageMagick Command: "convert -respect-parenthesis ( INPUT_IMAGE.jpg -colorspace gray -contrast-stretch 0 ) ( -clone 0 -colorspace gray -negate -lat 25x25+30% -contrast-stretch 0 ) -compose copy_opacity -composite -fill white -opaque none -alpha off -background white OUTPUT_IMAGE.jpg"
I tried to convert this code to Magick++ code and failed in "-lat", "-contrast-stretch" and "-compose" positions.
This is my c++ code so far:
Image backgroungImage;
backgroungImage.read("INPUT_IMAGE.jpg");
backgroungImage.colorSpace(GRAYColorspace);
backgroungImage.type(GrayscaleType);
backgroungImage.contrastStretch(0, QuantumRange);
backgroungImage.write("Partial_output.jpg");
If anyone has an idea or a better solution please let me know.
thanx in advance.
You're on the right track with -contrast-stretch. For -lat, remember that's an abbreviation of "Local Adaptive Threshold". So the C++ code would look like...
Image backgroundImage;
// INPUT_IMAGE.jpg
backgroundImage.read("INPUT_IMAGE.jpg");
// -colorspace gray
backgroundImage.colorSpace(GRAYColorspace);
// -contrast-stretch 0
backgroundImage.contrastStretch(0, QuantumRange);
// -clone 0
Image foregroundImage(backgroundImage);
// -negate
foregroundImage.negate();
// -lat 25x25+30%
foregroundImage.adaptiveThreshold(25, 25, QuantumRange * 0.30);
// -contrast-stretch 0
backgroundImage.contrastStretch(0, QuantumRange);
// -compose copy_opacity -composite
backgroundImage.composite(foregroundImage, 0, 0, CopyAlphaCompositeOp);
// -fill white -opaque none
backgroundImage.opaque(Color("NONE"), Color("WHITE"));
// -alpha off
backgroundImage.alpha(false);
// -background white
backgroundImage.backgroundColor(Color("WHITE"));
// OUTPUT_IMAGE.jpg
backgroundImage.write("OUTPUT_IMAGE.jpg");
Hope that helps!

How to detect an inclination of 90 degrees or 180?

In my project I deal with images which I don't know if they are inclined or not.
I work with C++ and OpenCV. I try with Hough transformation to determine the angle of inclination: if it is 90 or 180. But it doesn't give a result.
A link to example image (full resolution TIFF) here.
The following illustration is the full-res image scaled down and converted to PNG:
If I want to attack your image with the Hough lines method, I would do a Canny edge detection first, then find the Hough lines and then look at the generated lines. So it would look like this in ImageMagick - you can transform to OpenCV:
convert input.jpg \
\( +clone -canny x10+10%+30% \
-background none -fill red \
-stroke red -strokewidth 2 \
-hough-lines 9x9+150 \
-write lines.mvg \
\) \
-composite hough.png
And in the lines.mvg file, I can see the individual detected lines:
# Hough line transform: 9x9+150
viewbox 0 0 349 500
line 0,-3.74454 349,8.44281 # 160
line 0,55.2914 349,67.4788 # 206
line 1,0 1,500 # 193
line 0,71.3012 349,83.4885 # 169
line 0,125.334 349,137.521 # 202
line 0,142.344 349,154.532 # 156
line 0,152.351 349,164.538 # 155
line 0,205.383 349,217.57 # 162
line 0,239.453 349,245.545 # 172
line 0,252.455 349,258.547 # 152
line 0,293.461 349,299.553 # 163
line 0,314.464 349,320.556 # 169
line 0,335.468 349,341.559 # 189
line 0,351.47 349,357.562 # 196
line 0,404.478 349,410.57 # 209
line 349.39,0 340.662,500 # 187
line 0,441.484 349,447.576 # 198
line 0,446.484 349,452.576 # 165
line 0,455.486 349,461.578 # 174
line 0,475.489 349,481.581 # 193
line 0,498.5 349,498.5 # 161
I resized your image to 349 pixels wide (to make it fit on Stack Overflow and process faster), so you can see there are lots of lines that start at 0 on the left side of the image and end at 349 on the right side which tells you they go across the image, not up and down it. Also, you can see that the right end of the lines is generally 16 pixels lower than the left, so the image is rotated tan inverse (16/349) degrees.
Here is a fairly simple approach that may help you get started, or give you ideas that you can adapt. I use ImageMagick, but the concepts and techniques should be readily applicable in OpenCV.
First, I note that the image is rotated a few degrees and that gives the black triangle at top right, so the first thing I would consider is cropping the middle out of the image - i.e. removing around 10-15% off each side.
The next thing I note is that, the image is poorly scanned with lots of noisy, muddy grey areas. I would tend to want to blur these together so that they become a bit more uniform and can be thresholded.
So, if I want to do those two things in ImageMagick, I would do this:
convert input.tif \
-gravity center -crop 75x75%+0+0 \
-blur x10 -threshold 50% \
-negate \
stage1.jpg
Now, I can count the number of horizontal black lines that run the full width of the image (without crossing anything white). I do this by squidging the image till it is just a single pixel wide (but still the full original height) and counting the number of black rows:
convert stage1.jpg -resize 1x! -threshold 1 txt: | grep -c black
1368
And I do the same for vertical black lines that run the full height of the image from top to bottom, uninterrupted by white. I do that by squidging the image till it is a single pixel tall and the full original width:
convert stage1.jpg -resize x1! -threshold 1 txt: | grep -c black
0
Therefore there are 1,368 lines across the image and none up and down it, so I can say the dark lines in the original image tend to run left-right across the image rather than top-bottom up and down the image.

imread from openCV makes the image darker

I'm using openCV 2.4.9 and I have a problem with images.
I have this original imagem,
In C++ I do,
cv::Mat img = cv::imread(sourceImgPath, CV_LOAD_IMAGE_UNCHANGED);
imshow("test", img); //or imwrite(path, img);
And with imshow or imwrite I get always the following image,
So as you can see, it's darker and I have no idea why this happen. I have tried all the flags from imread but it does the same thing. Anyone can help?
Thanks for your time. I really appreciate your help.
Wazhup
According to ImageMagick it is in sRGB colourspace with a gamma of 0.4545. I suspect that is not what OpenCV is expecting and some gamma or colourspace correction is maybe required. Sorry, I could not post this as a comment (rather than an answer) because it is too big and the formatting would be ridiculous. Hopefully it is constructive and will help lead someone to a solution for you.
Image: brDaP.jpg
Format: JPEG (Joint Photographic Experts Group JFIF format)
Mime type: image/jpeg
Class: DirectClass
Geometry: 600x400+0+0
Units: Undefined
Type: TrueColor
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 8-bit
green: 8-bit
blue: 8-bit
Channel statistics:
Pixels: 240000
Red:
min: 0 (0)
max: 255 (1)
mean: 100.628 (0.39462)
standard deviation: 52.5382 (0.206032)
kurtosis: 0.337274
skewness: 0.482249
Green:
min: 0 (0)
max: 255 (1)
mean: 108.882 (0.426989)
standard deviation: 55.0518 (0.215889)
kurtosis: -0.330334
skewness: 0.193815
Blue:
min: 0 (0)
max: 255 (1)
mean: 128.997 (0.505872)
standard deviation: 70.9162 (0.278103)
kurtosis: -1.38343
skewness: -0.0647535
Image statistics:
Overall:
min: 0 (0)
max: 255 (1)
mean: 112.836 (0.442493)
standard deviation: 60.0557 (0.235513)
kurtosis: -0.536439
skewness: 0.289801
Rendering intent: Perceptual
Gamma: 0.454545 <--------------------- GAMMA
Chromaticity:
red primary: (0.64,0.33)
green primary: (0.3,0.6)
blue primary: (0.15,0.06)
white point: (0.3127,0.329)
Background color: white
Border color: srgb(223,223,223)
Matte color: grey74
Transparent color: black
Interlace: None
Intensity: Undefined
Compose: Over
Page geometry: 600x400+0+0
Dispose: Undefined
Iterations: 0
Compression: JPEG
Quality: 99
Orientation: Undefined
Properties:
date:create: 2014-10-14T22:03:59+01:00
date:modify: 2014-10-14T22:03:59+01:00
icc:copyright: Copyright (c) Eastman Kodak Company, 1999, all rights reserved.
icc:description: ProPhoto RGB
icc:manufacturer: KODAK
icc:model: Reference Output Medium Metric(ROMM)
jpeg:colorspace: 2
jpeg:sampling-factor: 1x1,1x1,1x1
signature: c436a68fe624fd471fcd3563b7dafa154ec4f17e784a448a2863a24856c70be6
Profiles:
Profile-icc: 940 bytes
Artifacts:
filename: brDaP.jpg
verbose: true
Tainted: False
Filesize: 210KB
Number pixels: 240K
Pixels per second: 24MB
User time: 0.000u
Elapsed time: 0:01.009
Version: ImageMagick 6.8.9-7 Q16 x86_64 2014-09-10 http://www.imagemagick.org
After opening the file with GIMP, it seems the image has a ProPhoto embedded color profile. GIMP can change the color profile into a normal RGB like the one below, which will be opened as usual using OpenCV or Matlab.

How do i create my own clasiifier

Now I am creating my own classifier for face detection.I have two folder one for storing positive images and other for storing negative images. And I make .txt files for both. Now I want to create training samples of positive imgaes. So I give command 'opencv_createsamples -info positives.txt -vec myvec.vec -w 24 -h 24 '. But It shows like this.It doesn't create any samples.What is the reason?Could any one help me. Thanks in advance.
Info file name: positives.txt
Img file name: (NULL)
Vec file name: myvec.vec
BG file name: (NULL)
Num: 1000
BG color: 0
BG threshold: 80
Invert: FALSE
Max intensity deviation: 40
Max x angle: 1.1
Max y angle: 1.1
Max z angle: 0.5
Show samples: FALSE
Width: 24
Height: 24
Create training samples from images collection...
positives.txt(1) : parse errorDone. Created 0 samples
The info file should not contain only file names, but also ROI specification.
each line should look like this:
path/to/image.bmp num_rois x y width height x y width height ...
For example if you have files that are exactly as big as the sample size, each line should be:
path/to/image.bmp 1 0 0 24 24
note that the path to the image file should be relative to the location of the info file. also the default number of samples is 1000, if you want to include all the samples in your info file you should specify it through the command line.
a good guide can be found on the opencv web site: http://docs.opencv.org/doc/user_guide/ug_traincascade.html#positive-samples