Magick++ ``depth`` does not behave the same as ``convert -depth`` - c++

I discovered via my previous question that depth appears to work differently when I use it in ImageMagick's convert vs Magick++.
CLI version and result
Using:
$ convert /foo/bar.ppm -depth 1 /foo/out.ppm
I get an output image which, upon inspection, shows a 1-bit color depth:
$ identify /foo/out.ppm
out.ppm PPM (blah blah) 1-bit sRGB (blah blah)
C++ version and result
Using the code:
#include <Magick++.h>
int main(int argc, char **argv) {
Magick::InitializeMagick(*argv);
Magick::Image img;
img.read("/foo/bar.ppm");
Magick::Image temp_img(img);
temp_img.depth(1);
temp_img.write("/foo/out.ppm");
return 0;
}
Compiled using the command:
g++ -std=c++17 test.cpp -o test `Magick++-config --cppflags --cxxflags --ldflags --libs`
Produces the output:
$ identify /foo/out.ppm
out.ppm PPM (blah blah) 8-bit sRGB (blah blah)
Hardware
I have run this with the same result on on:
Raspberry Pi - Raspbian 10 (buster)
Laptop - Ubuntu 18.04 (bionic beaver)
Software (on the RPi)
$ apt list --installed | grep magick
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
graphicsmagick-libmagick-dev-compat/stable,now 1.4+really1.3.35-1~deb10u1 all [installed]
imagemagick-6-common/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 all [installed,automatic]
imagemagick-6.q16/now 8:6.9.10.23+dfsg-2.1 armhf [installed,upgradable to: 8:6.9.10.23+dfsg-2.1+deb10u1]
imagemagick/now 8:6.9.10.23+dfsg-2.1 armhf [installed,upgradable to: 8:6.9.10.23+dfsg-2.1+deb10u1]
libgraphics-magick-perl/stable,now 1.4+really1.3.35-1~deb10u1 armhf [installed,automatic]
libgraphicsmagick++-q16-12/stable,now 1.4+really1.3.35-1~deb10u1 armhf [installed,automatic]
libgraphicsmagick++1-dev/stable,now 1.4+really1.3.35-1~deb10u1 armhf [installed,automatic]
libgraphicsmagick-q16-3/stable,now 1.4+really1.3.35-1~deb10u1 armhf [installed,automatic]
libgraphicsmagick1-dev/stable,now 1.4+really1.3.35-1~deb10u1 armhf [installed,automatic]
libmagick++-6-headers/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 all [installed,auto-removable]
libmagick++-6.q16-8/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 armhf [installed,auto-removable]
libmagickcore-6-arch-config/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 armhf [installed,auto-removable]
libmagickcore-6-headers/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 all [installed,auto-removable]
libmagickcore-6.q16-6-extra/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 armhf [installed,automatic]
libmagickcore-6.q16-6/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 armhf [installed,automatic]
libmagickwand-6-headers/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 all [installed,auto-removable]
libmagickwand-6.q16-6/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 armhf [installed,automatic]
The Picture
I've tested with multiple input files with sRGB type. I convert everything to NetBPM format before starting my test e.g.:
convert yourimage.jpg /foo/bar.ppm
The Question
Why is the C++ different from the Bash version? They should be linking to the exact same code in the background. The input value for depth does not need to be a special type (Magick::Image.depth takes size_t). Is there something in my installation which is messing this up? I know most of it is based on ImageMagick v6 because debian repos are notoriously slow, but nothing has changed (to my knowledge) in the source code which should effect the depth.
What else doesn't work?
Quantization
Adding:
temp_img.quantizeColorSpace(Magick::GRAYColorspace);
temp_img.quantizeColors(1);
temp_img.quantize( );
to the code should also be a method which reduces the color depth. Again, this results in an 8-bit image in C++.
Monochrome
This results in an 8-bit image in both CLI and C++

Closest solution I can think of is to user the "PBM" format.
Generating a test image with the following.
convert -size 10x10 plasma: input.jpg && convert input.jpg input.ppm
Just using the Magick::Image.magick method.
#include <Magick++.h>
int main(int argc, char **argv) {
Magick::InitializeMagick(*argv);
Magick::Image img;
img.read("input.ppm");
Magick::Image temp_img(img);
temp_img.magick("PBM");
temp_img.depth(1);
temp_img.write("output.ppm");
return 0;
}
We get the following file structure...
$ hexdump -C output.ppm
00000000 50 34 0a 31 30 20 31 30 0a 00 00 00 00 00 00 06 |P4.10 10........|
00000010 00 ff 80 ff c0 ff c0 ff c0 ff c0 ff c0 |.............|
0000001d
If we want the ASCII representation of the binary data, just disable the compression.
Magick::Image temp_img(img);
temp_img.compressType(Magick::NoCompression);
temp_img.magick("PBM");
temp_img.depth(1);
temp_img.write("output.ppm");
Which would yield the following...
$ hexdump -C output2.ppm
00000000 50 31 0a 31 30 20 31 30 0a 30 20 30 20 30 20 30 |P1.10 10.0 0 0 0|
00000010 20 30 20 30 20 30 20 30 20 30 20 30 20 0a 30 20 | 0 0 0 0 0 0 .0 |
00000020 30 20 30 20 30 20 30 20 30 20 30 20 30 20 30 20 |0 0 0 0 0 0 0 0 |
00000030 30 20 0a 30 20 30 20 30 20 30 20 30 20 30 20 30 |0 .0 0 0 0 0 0 0|
00000040 20 30 20 30 20 30 20 0a 30 20 30 20 30 20 30 20 | 0 0 0 .0 0 0 0 |
00000050 30 20 31 20 31 20 30 20 30 20 30 20 0a 31 20 31 |0 1 1 0 0 0 .1 1|
00000060 20 31 20 31 20 31 20 31 20 31 20 31 20 31 20 30 | 1 1 1 1 1 1 1 0|
00000070 20 0a 31 20 31 20 31 20 31 20 31 20 31 20 31 20 | .1 1 1 1 1 1 1 |
00000080 31 20 31 20 31 20 0a 31 20 31 20 31 20 31 20 31 |1 1 1 .1 1 1 1 1|
00000090 20 31 20 31 20 31 20 31 20 31 20 0a 31 20 31 20 | 1 1 1 1 1 .1 1 |
000000a0 31 20 31 20 31 20 31 20 31 20 31 20 31 20 31 20 |1 1 1 1 1 1 1 1 |
000000b0 0a 31 20 31 20 31 20 31 20 31 20 31 20 31 20 31 |.1 1 1 1 1 1 1 1|
000000c0 20 31 20 31 20 0a 31 20 31 20 31 20 31 20 31 20 | 1 1 .1 1 1 1 1 |
000000d0 31 20 31 20 31 20 31 20 31 20 0a |1 1 1 1 1 .|
000000db
Don't know if that's exactly which you need, but should get you on track. Also might be worth reviewing WritePNMImage method in coders/pnm.c file (same file for ImageMagick-6).

Solution
It appears that this problem was solved by removing problem packages previously downloaded from the Debian apt repository. It is difficult to nail down which was the offending part, but I removed:
sudo apt remove graphicsmagick-libmagick-dev-compat imagemagick-6-common imagemagick-6.q16 imagemagick
Next, I built ImageMagick from source, following the directions here.
Explanation
The solution was not simply a version change, which would be an understandable confusion since during the source build, I upgraded from v6 of ImageMagick still in the Debian repository to v7. However, tests by #emcconville were performed on both v6 and v7 without reproducing the errors I experienced. Presumably, since he is involved with ImageMagick development, he uses a copy built from source rather than what is available from apt-get. Therefore, we can safely assume that the problem is either in one of the Debian packages or caused by some incorrect combination of packages on the affected machine.

Related

Issue generating DAG using CausalFS cpp package

Link to CausalFS GitHub I'm using v.2.0 of CausalFS cpp package by Kui Yu.
Upon running the structural learning algos, my DAG and MB are not matching.
I'm trying to generate a DAG based on the data given in the CDD/data/data.txt directory and CDD/data.txt via some of the Local-to-global structure learning algos mentioned in the manual (PCMB-CSL, STMB-CSL etc.). Running the commands as given by the manual (pg. 18 of 26).
But my resulting DAG is just filled with zeros (for the most part). Given that this is a example dataset that looks suspicious. Upon then checking CDD/mb/mb.out I find that the Markov blankets for the variables do not agree with the DAG output.
For ex, running ./main ./data/data.txt ./data/net.txt 0.01 PCMB-CSL "" "" -1 gives a 1 at position (1,22) (one-indexed) only (relaxing alpha value to 0.1 (kept at 0.01 in ex) gives just another 1). However, this doesn't agree with the output MB for each variable, which looks like (upon running IAMB as ./main ./data/data.txt ./net/net.txt 0.01 IAMB all "" "")-
0 21
1 22 26 28
2 29
3 14 21
4 5 12
5 4 12
6 8 12
7 8 12
8 6 7 12
9 11 15
10 35
11 9 12 15 33
12 4 6 7 8 11 13
13 8 12 14 15 17 30 34
14 3 13 20
15 8 9 11 13 14 17 30
16 15
17 13 15 18 27 30
18 17 19 20 27
19 18 20
20 14 18 21 28
21 0 3 20 26
22 1 21 23 24 28
23 1 22 24
24 5 22 23 25
25 24
26 1 21 22
27 17 18 28 29
28 1 18 21 22 27 29
29 2 27
30 13 14 15 17
31 34
32 15 18 34
33 11 12 32 35 36
34 30 31 32 35 36
35 10 33 34
36 33 34 35
Such an MB profile suggests the DAG to be much more connected.
I would love to hear suggestions from people who've managed to get the package to behave appropriately. I just do not understand the error here from my side. (I'm running on PopOS 20.04)
Thanks a bunch <3
P.S- The files just continue to write upon rerunning the code, so make sure to appropriately delete them.

Deleting the last characters in the specific columns

I have a sample text file with following columns
scff2 54 92 aa_bb_c4_1024_0_2 scff2 30 18 aa_bb_c4_1024_0_2
scff8 80 96 aa_bb_c4_24_0_2 scff8 14 42 aa_bb_c4_24_0_2
scff1 20 25 aa_bb_c4_98_0_1 scff4 11 25 aa_bb_c4_13_0_1
scff6 16 61 aa_bb_c4_84_0_1 scff6 15 16 aa_bb_c4_84_0_2
I would like remove the last characters in the column 4 and column 8 like following using awk
scff2 54 92 aa_bb_c4_1024_0 scff2 30 18 aa_bb_c4_1024_0
scff8 80 96 aa_bb_c4_24_0 scff8 14 42 aa_bb_c4_24_0
scff1 20 25 aa_bb_c4_98_0 scff4 11 25 aa_bb_c4_13_0
scff6 16 61 aa_bb_c4_84_0 scff6 15 16 aa_bb_c4_84_0
I tried using following script sed -i.bak 's/_[0-9]*$//' sample.txt but it did remove the characters after the last underscore in 8th column but not in the 4th column. Can some one can guide me in achieving my desired output. Thanks in advance.
You can use sub() in awk to perform a substitution in a specific field.
awk '{sub(/_[0-9]*$/, "", $4); sub(/_[0-9]*$/, "", $8); print}' sample.txt
It looks like all you need is:
$ sed 's/_[0-9]\( \|$\)/\1/g' file
scff2 54 92 aa_bb_c4_1024_0 scff2 30 18 aa_bb_c4_1024_0
scff8 80 96 aa_bb_c4_24_0 scff8 14 42 aa_bb_c4_24_0
scff1 20 25 aa_bb_c4_98_0 scff4 11 25 aa_bb_c4_13_0
scff6 16 61 aa_bb_c4_84_0 scff6 15 16 aa_bb_c4_84_0
or if your sed supports -E to enable EREs (which I expect yours does since you're using -i):
$ sed -E 's/_[0-9]( |$)/\1/g' file
scff2 54 92 aa_bb_c4_1024_0 scff2 30 18 aa_bb_c4_1024_0
scff8 80 96 aa_bb_c4_24_0 scff8 14 42 aa_bb_c4_24_0
scff1 20 25 aa_bb_c4_98_0 scff4 11 25 aa_bb_c4_13_0
scff6 16 61 aa_bb_c4_84_0 scff6 15 16 aa_bb_c4_84_0
or as #GlennJackman pointed out in the comments, with GNU sed (the above would work with other seds too, e.g. OSX sed), it'd be:
sed 's/_[0-9]\>//g'
Sometimes it's useful to store the result of a substitution in gawk :
$ awk '{$4=gensub(/_[0-9]$/, "", 1, $4); $8=gensub(/_[0-9]$/, "", 1, $8)}1' file
Output :
scff2 54 92 aa_bb_c4_1024_0 scff2 30 18 aa_bb_c4_1024_0
scff8 80 96 aa_bb_c4_24_0 scff8 14 42 aa_bb_c4_24_0
scff1 20 25 aa_bb_c4_98_0 scff4 11 25 aa_bb_c4_13_0
scff6 16 61 aa_bb_c4_84_0 scff6 15 16 aa_bb_c4_84_0
But #Barmar solution is smarter/shorter/lighter
Not in all awk implementations : not nawk, need GNU awk or maybe mawks
In GNU awk, everything ending in `_[0-9]+' removed:
$ awk '{gsub(/_[0-9]+\>/,"")}1' file
scff2 54 92 aa_bb_c4_1024_0 scff2 30 18 aa_bb_c4_1024_0
scff8 80 96 aa_bb_c4_24_0 scff8 14 42 aa_bb_c4_24_0
...
awk '{gsub(/_0_./,"_0")}1' file
scff2 54 92 aa_bb_c4_1024_0 scff2 30 18 aa_bb_c4_1024_0
scff8 80 96 aa_bb_c4_24_0 scff8 14 42 aa_bb_c4_24_0
scff1 20 25 aa_bb_c4_98_0 scff4 11 25 aa_bb_c4_13_0
scff6 16 61 aa_bb_c4_84_0 scff6 15 16 aa_bb_c4_84_0

Quantization tabels of different sizes

I am doing some research on image compression via discrete cosine transformations and i want to change to quantization tables sizes so that i can study what happens when i change the matrix sizes that i divide my pictures into. The standard sub-matrix size is 8X8 and there is a lot of tables for those dimensions. For example the standard JPEG quantization table (that i use) is:
standardmatrix8 = np.matrix('16 11 10 16 24 40 51 61;\
12 12 14 19 26 58 60 55;\
14 13 16 24 40 57 69 56;\
14 17 22 29 51 87 80 62;\
18 22 37 56 68 109 103 77;\
24 35 55 64 81 104 103 92;\
49 64 78 77 103 121 120 101;\
72 92 95 98 112 100 103 99').astype('float')
I have assumed that the quantization tabel for 2X2 and 4X4 would be:
standardmatrix2 = np.matrix('16 11; 12 12.astype('float')
standardmatrix4 = np.matrix('16 11 10 16;
12 12 14 19;
14 13 16 24;
18 22 37 56').astype('float')
Since the entries in the standard table correspond to the same frequencies in the smaller matrixes.
But what about a quantization with dimentions 16X16, 24X24 and so on. I know that the standard quantization tabels are worked out by experiments and can't be calculated from some formula, but i assume that someone have tried changing the matrix sizes before me! Where can i find these tabels? Or can i just make something up and scale the last entries to higher frequenzies?

excel, vba or regex to copy values downwards based on repeated values

I have the following records:
62
STARTHERE 1.1 vol. 84 no. 1 1996 01.1 A 0 1 1996 04 24 0
STARTHERE 1.2 vol. 84 no. 2 1996 01.2 A 0 1 1996 05 23 0
STARTHERE 1.3 vol. 84 no. 3 1996 01.3 A 1 1 1996 08 13 0
STARTHERE 1.4 vol. 84 no. 4 1996 01.4 A 0 1 1996 10 15 0
STARTHERE 1.5 vol. 84 no. 5 1996 01.5 A 0 1 1997 01 22 0
STARTHERE 1.6 vol. 84 no. 6 1996 01.6 A 0 1 1997 02 10 0
63
STARTHERE 1.1 95:1 Feb 2002 1.1 A 0 1 2002 06 03 0
STARTHERE 1.2 95:2 Apr 2002 1.2 A 0 1 2002 06 17 0
STARTHERE 1.3 95:3 Jun 2002 1.3 A 0 1 2002 07 18 0
STARTHERE 1.4 95:4 Aug 2002 1.4 A 0 1 2003 02 24 0
STARTHERE 1.5 95:5 Oct 2002 1.5 A 0 1 2003 02 24 0
64
65
STARTHERE 1.1 34:1 Mar 1996 1.1 A 0 1 1996 07 16 0
STARTHERE 1.2 34:2 Jun 1996 1.2 A 0 1 1996 09 19 0
STARTHERE 1.3 34:3 Sep 1996 1.3 A 0 1 1996 12 17 0
I don't know if this is possible in excel, vba in excel or even through regex. I want to fill the lowest numerical value (e.g. 62) and replace the lower rows with values "STARTHERE" up until the next numerical value (63). Right now, it's done manually but I was thinking if there is a way of doing this mechanically. Through excel formula, VBA, or regex, as these are what I'm familiar with. So that I can get below, it's okay also that the 62 with blank value to the right are stripped but I'm fine even if it's not:
62
62 1.1 vol. 84 no. 1 1996 01.1 A 0 1 1996 04 24 0
62 1.2 vol. 84 no. 2 1996 01.2 A 0 1 1996 05 23 0
62 1.3 vol. 84 no. 3 1996 01.3 A 1 1 1996 08 13 0
62 1.4 vol. 84 no. 4 1996 01.4 A 0 1 1996 10 15 0
62 1.5 vol. 84 no. 5 1996 01.5 A 0 1 1997 01 22 0
62 1.6 vol. 84 no. 6 1996 01.6 A 0 1 1997 02 10 0
62
62 1.1 95:1 Feb 2002 1.1 A 0 1 2002 06 03 0
63 1.2 95:2 Apr 2002 1.2 A 0 1 2002 06 17 0
63 1.3 95:3 Jun 2002 1.3 A 0 1 2002 07 18 0
63 1.4 95:4 Aug 2002 1.4 A 0 1 2003 02 24 0
63 1.5 95:5 Oct 2002 1.5 A 0 1 2003 02 24 0
64
65
65 1.1 34:1 Mar 1996 1.1 A 0 1 1996 07 16 0
65 1.2 34:2 Jun 1996 1.2 A 0 1 1996 09 19 0
65 1.3 34:3 Sep 1996 1.3 A 0 1 1996 12 17 0
Many thanks!
I assume this data is from an Excel spreadsheet, with both the numerical values and the value "STARTHERE" are on the first column (column A). The other data are on column B, C, etc.
Basically, I will loop through the first column from the top to the bottom row. If the value within the selector cell is not a number, it will be equal to the one right above it. If it is, then we skip to the next cell.
Sub help()
ActiveSheet.Columns(1).NumberFormat = "0"
For i = 1 To ActiveSheet.UsedRange.Rows.count
If Not Information.IsNumeric(Cells(i, 1)) Then Cells(i, 1).value = Cells(i - 1, 1).value
Next i
End Sub

Import records from a flat txt file with records delimited spacing?

I consulted as I can configure SPOON for correct import of data, knowing that I have the data delimited by spaces.
And if it affects the import process in the penultimate record "SP_SEC" is not always a record and may be blank, affect the import?
I show the data as I have:
SP_NLE SP_LIB SP_DEP SP_PRV SP_DST SP_APP SP_APM SP_NOM SP_NAC SP_SEX SP_GRI SP_SEC SP_DOC
00000001 000090 70 03 04 BARDALES AHUANARI RENE 19111116 2 10 8
00000003 000001 25 01 01 MEZA DE RUIZ CARLOTA 19400119 2 20 1 1
00000004 000001 25 01 01 BARDALES TORRES JOYCE 19580122 2 20 9 1
00000005 244246 25 01 02 RAMIREZ RUIZ FRANCISCO 19600309 1 20 7 1
00000006 000001 25 01 01 SILVA RIVERA DE RIOS ALICIA 19570310 2 20 5 1
00000008 000001 25 01 01 PACAYA MANIHUARI MANUEL 19401215 1 10 1 1
00000009 233405 25 01 02 TORRES MUĂ‘OZ GLADYS 19650902 2 20 0 1
00000010 000508 25 01 01 OLIVOS RODAS BRITALDO 19510924 1 20 3 1
00000011 000001 25 01 01 ESCUDERO HERNANDEZ JULIA ISABEL 19351118 2 30 1
00000012 000001 25 01 01 YAICATE TARICUARIMA RICARDO 19560118 1 20 0 1
00000013 000001 25 01 01 ESPINOZA DE PINEDO ALEGRIA 19371108 2 10 1
00000014 000001 25 01 01 GARCIA PINCHI RICARDO 19650315 1 30 6 1
00000015 236352 09 01 01 LAO ESPINOZA ALINA 19601217 2 30 4 1
00000017 219532 25 01 01 YAICATE YAHUARCANI OLGA 19530706 2 10 1 1
Please aid, which must be placed in the section "Regular Expression" and the Content tab should be placed in the section of "Separator", or other value in any other section?
Any suggestions.