{"id":1290,"date":"2017-04-28T11:30:11","date_gmt":"2017-04-28T02:30:11","guid":{"rendered":"http:\/\/rageworx.info\/?p=1290"},"modified":"2017-04-29T00:49:39","modified_gmt":"2017-04-28T15:49:39","slug":"tinydicom-rawprocessor-lesson-2","status":"publish","type":"post","link":"https:\/\/rageworx.info\/?p=1290","title":{"rendered":"tinydicom + rawprocessor lesson #2"},"content":{"rendered":"<p><a href=\"http:\/\/rageworx.info\/wp-content\/uploads\/2017\/04\/libtinydcm_example.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1291\" src=\"http:\/\/rageworx.info\/wp-content\/uploads\/2017\/04\/libtinydcm_example.jpg\" alt=\"\" width=\"389\" height=\"369\" \/><\/a> Now it&#8217;s time to next step for using my open sources,\u00a0 And here I like to introduce how loads DCM and what it contains inside tags.<\/p>\n<p>Just read my example code to read DICOM tags from DCM file, it should help what inside.<\/p>\n<pre class=\"lang:c++ decode:true\" title=\"Loading DCM and check what contains inside.\">#ifdef __APPLE__\r\n    #include &lt;sys\/uio.h&gt;\r\n#elif _WIN32\r\n    #include &lt;io.h&gt;\r\n#else\r\n    #include &lt;sys\/io.h&gt;\r\n#endif\r\n\r\n#include &lt;cstdio&gt;\r\n#include &lt;cstdlib&gt;\r\n\r\n\/\/ -- std ---\r\n#include &lt;string&gt;\r\n#include &lt;vector&gt;\r\n\r\nusing namespace std;\r\n\r\n\/\/ -- other headers --\r\n#include \"libdcm.h\"\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\n#define MADE_DATE               \"2017-04-18-0\"\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\nconst char sampledcm[] = \"SIMFIT.dcm\";\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\nvoid testDCM()\r\n{\r\n    printf( \"#TEST: Loading DCM #\\n\" );\r\n    printf( \"Loading DCM file : %s ... \", sampledcm );\r\n\r\n    if ( OpenDCM( sampledcm ) == true )\r\n    {\r\n        printf( \"Ok.\\n\" );\r\n\r\n        printf( \"Check elements : \" );\r\n        int elemsz = GetElementCount();\r\n        printf( \"%d elements found.\\n\", elemsz );\r\n\r\n        if ( elemsz &gt; 0 )\r\n        {\r\n            for( int cnt=0; cnt&lt;elemsz; cnt++ )\r\n            {\r\n                DCMTagElement* elem = NULL;\r\n                if ( GetElement( cnt, &amp;elem ) &gt; 0  )\r\n                {\r\n                    printf( \"\\t[%03d : %c%c] ID = %04X:%04X , size = %d bytes \\n\",\r\n                            cnt + 1,\r\n                            elem-&gt;VRtype[0],\r\n                            elem-&gt;VRtype[1],\r\n                            ( elem-&gt;id &amp; 0xFFFF0000 ) &gt;&gt; 16,\r\n                            elem-&gt;id &amp; 0x0000FFFF,\r\n                            elem-&gt;size );\r\n\r\n                    delete elem;\r\n                }\r\n            }\r\n        }\r\n\r\n        CloseDCM();\r\n    }\r\n}\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\nint main( int argc, char** argv )\r\n{\r\n    printf( \"librawprocessor + libtinydicom, examples : %s\\n\", MADE_DATE);\r\n    printf( \"(C)2017, Raph.K.\\n\");\r\n\r\n    testDCM();\r\n \r\n    return 0;\r\n}<\/pre>\n<p>It may compiles with libtinydicom.a linkage as well, just compile your code with <code>-ltinydicom -L{libtinydicom.a directory from your path}<\/code>. Or, just follow my way &#8211; Make an empty directory in your working directory &#8211;\u00a0 I like to recommend to make a directory as like &#8216;projects&#8217;. Then make a new again for unique name to check for next time, or continue to more works : recommend &#8216;dcmtest1&#8217; or &#8216;dcmtest2&#8217;. So you may now placed to <code>{Your home directory}\/projects\/dcmtest1<\/code> when you had followed my recommendation. Now make a empty cpp file with any editor like vim, then copy &amp; paste my example, then save it up and quit editor. Then copy prebuilt &#8220;libtinydicom.a&#8221; and &#8220;libdcm.h&#8221; into your current directory &#8211; if you didn&#8217;t prebuilt? just build it first. and type like this.<\/p>\n<p><code>g++ main.cpp -ltinydicom -o test1<\/code><\/p>\n<p>You may check test1 or test1.exe (on Windows).<br \/>\nNow you need download sample DCM file from here:<\/p>\n<p>http:\/\/tomintechsupport.com\/dicom\/smpte_simfit\/<\/p>\n<p>If you have wget, you can do :<\/p>\n<p><code>wget http:\/\/tomintechsupport.com\/download\/SIMFIT.dcm<\/code><\/p>\n<p>Now you have SIMFIT.dcm and compiled binary with same directory. Just type your binary name. And check result. 87 items may displayed with sizes.<\/p>\n<p>&nbsp;<\/p>\n<p>Then, try to next step, save raw pixel image to a new file. See my example source.<\/p>\n<pre class=\"lang:c++ decode:true \" title=\"load DCM and save pixel image to a new file.\">#ifdef __APPLE__\r\n    #include &lt;sys\/uio.h&gt;\r\n#elif _WIN32\r\n    #include &lt;io.h&gt;\r\n#else\r\n    #include &lt;sys\/io.h&gt;\r\n#endif\r\n\r\n#include &lt;cstdio&gt;\r\n#include &lt;cstdlib&gt;\r\n\r\n\/\/ -- std ---\r\n#include &lt;string&gt;\r\n#include &lt;vector&gt;\r\n\r\nusing namespace std;\r\n\r\n\/\/ -- other headers --\r\n#include \"rawprocessor.h\"\r\n#include \"libdcm.h\"\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\n#define MADE_DATE               \"2017-04-18-0\"\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\nconst char sampledcm[] = \"SIMFIT.dcm\";\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\nvoid testDCM2RAW()\r\n{\r\n    printf( \"#TEST: DCM to RAW image#\\n\" );\r\n    printf( \"Loading DCM file : %s ... \", sampledcm );\r\n\r\n    if ( OpenDCM( sampledcm ) == true )\r\n    {\r\n        printf( \"Ok.\\n\" );\r\n\r\n        printf( \"Check pixel data elements : \" );\r\n\r\n        ImageInformation iinfo = {0};\r\n\r\n        if ( ReadPixelData( &amp;iinfo ) == true )\r\n        {\r\n            printf( \"Ok.\\n\" );\r\n\r\n            \/\/ Convert DCM raw image info to RAW image processor.\r\n\r\n            RAWProcessor* rawproc = new RAWProcessor();\r\n\r\n            if ( rawproc != NULL )\r\n            {\r\n                int datasz = 2;\r\n\r\n                if ( iinfo.bpp &lt;= 8 )\r\n                {\r\n                    datasz = 1;\r\n                }\r\n\r\n                printf( \"Converting to RAW image ... \" );\r\n                bool retb = \\\r\n                rawproc-&gt;LoadFromMemory( (const char*)iinfo.pixels,\r\n                                         iinfo.width * iinfo.height * datasz,\r\n                                         0, \/\/\/ No transform\r\n                                         iinfo.height );\r\n                if ( retb == true )\r\n                {\r\n                    \/\/ Make RAW image to simply dumped as a file.\r\n                    char tmpstr[128] = {0};\r\n\r\n                    sprintf( tmpstr, \"rawdump_w%d_h%d.raw\", iinfo.width, iinfo.height );\r\n\r\n                    if ( rawproc-&gt;SaveToFile( tmpstr ) == true )\r\n                    {\r\n                        printf( \"Ok, dumped a file : %s\\n\", tmpstr );\r\n\r\n                        printf( \"raw image sizes : %d x %d\\n\", rawproc-&gt;Width(), rawproc-&gt;Height() );\r\n                    }\r\n                    else\r\n                    {\r\n                        printf( \"Failed to dump a file.\\n\" );\r\n                    }\r\n\r\n                    printf( \"Finding window center and width ... \" );\r\n                    \/\/ And then, process a little.\r\n                    \/\/ Find DICOM window center and width.\r\n\r\n                    DCMTagElement* dcmtag = NULL;\r\n\r\n                    unsigned w_center = 0;\r\n                    unsigned w_width  = 0;\r\n                    int      l_min    = 0;\r\n                    int      l_max    = 0;\r\n\r\n                    dcmtag = FindElement( 0x00281050 ); \/\/\/ window center\r\n                    if ( dcmtag != NULL )\r\n                    {\r\n                        w_center = atoi( dcmtag-&gt;staticbuffer );\r\n                    }\r\n\r\n                    dcmtag = FindElement( 0x00281051 ); \/\/\/ window width\r\n                    if ( dcmtag != NULL )\r\n                    {\r\n                        unsigned w_width = atoi( dcmtag-&gt;staticbuffer );\r\n                        if ( ( w_width &gt; 0 ) &amp;&amp; ( w_center == 0 ) )\r\n                        {\r\n                            w_center = w_width \/ 2;\r\n                        }\r\n\r\n                        l_max = w_center + w_width \/ 2;\r\n                        l_min = w_center - w_width \/ 2;\r\n\r\n                        if ( l_min &lt; 0 )\r\n                        {\r\n                            l_min = 0;\r\n                        }\r\n                    }\r\n\r\n                    if ( l_min &lt; l_max )\r\n                    {\r\n                        printf( \"Ok,\\nProcessing to thresholded image ... \" );\r\n\r\n                        \/\/ Make thresholded image.\r\n                        RAWProcessor::WeightAnalysisReport wreport = {0};\r\n                        rawproc-&gt;GetAnalysisReport( wreport );\r\n                        wreport.threshold_wide_min = l_min;\r\n                        wreport.threshold_wide_max = l_max;\r\n\r\n                        vector&lt; unsigned short &gt; thresholded;\r\n\r\n                        if ( rawproc-&gt;Get16bitThresholdedImage( wreport, &amp;thresholded ) == true )\r\n                        {\r\n                            RAWProcessor* rawproc_th = new RAWProcessor();\r\n                            if ( rawproc_th != NULL )\r\n                            {\r\n                                bool retb = \\\r\n                                rawproc_th-&gt;LoadFromMemory( (const char*) thresholded.data(),\r\n                                                            thresholded.size() * sizeof( unsigned short ),\r\n                                                            0,\r\n                                                            rawproc-&gt;Height() );\r\n\r\n                                if ( retb == true )\r\n                                {\r\n                                    printf( \"Ok.\\n\" );\r\n\r\n                                    sprintf( tmpstr,\r\n                                             \"rawposteffected_w%d_h%d.raw\",\r\n                                             rawproc_th-&gt;Width(),\r\n                                             rawproc_th-&gt;Height() );\r\n\r\n                                    rawproc_th-&gt;SaveToFile( tmpstr );\r\n                                }\r\n                                else\r\n                                {\r\n                                    printf( \"Failed to load image from memory.\\n\" );\r\n                                }\r\n\r\n                                delete rawproc_th;\r\n                            }\r\n                        }\r\n                        else\r\n                        {\r\n                            printf( \"Failed to get thresholded image.\\n\" );\r\n                        }\r\n                    }\r\n\r\n                    delete rawproc;\r\n                }\r\n                else\r\n                {\r\n                    printf( \"Failure.\\n \");\r\n                }\r\n\r\n            }\r\n        }\r\n        else\r\n        {\r\n            printf( \"Failure.\\n\" );\r\n        }\r\n\r\n        CloseDCM();\r\n    }\r\n}\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\nint main( int argc, char** argv )\r\n{\r\n    printf( \"librawprocessor + libtinydicom, examples : %s\\n\", MADE_DATE);\r\n    printf( \"(C)2017, Raph.K.\\n\");\r\n\r\n    testDCM2RAW();\r\n\r\n    return 0;\r\n}\r\n<\/pre>\n<p>Now you need prebuilt librawprocessor.a and rawprocessor.h file in your directory with example source code. It proceeds read SIMFIT.DCM and export pixel image information, then writes to a file.<\/p>\n<p>Important points is &#8216;Checking Window center and width&#8217; from DICOM tag ID 0028:1050 and 0028:1051. These tags contains information of window center and width, and it must applied to exported image. So I used Get16bitThresholdedImage() method to make windowed image.<\/p>\n<p>If you need more detailed? just let left a guestbook <a href=\"http:\/\/rageworx.info\/index.php\/guest\/\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>.<\/p>\n<p>Next lesson may using libPNG, and make raw image to 8bit grey scaled image to see in common image viewing programs.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Now it&#8217;s time to next step for using my open sources,\u00a0 And here I like to introduce how loads DCM and what it contains inside tags. Just read my example code to read DICOM tags from DCM file, it should help what inside. #ifdef __APPLE__ #include &lt;sys\/uio.h&gt; #elif _WIN32 #include&#8230; <a href=\"https:\/\/rageworx.info\/?p=1290\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,476,3],"tags":[487,477,447,478],"class_list":["post-1290","post","type-post","status-publish","format-standard","hentry","category-development","category-lesson","category-raphs","tag-examples","tag-lesson","tag-librawprocessor","tag-libtinydicom"],"_links":{"self":[{"href":"https:\/\/rageworx.info\/index.php?rest_route=\/wp\/v2\/posts\/1290","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rageworx.info\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rageworx.info\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rageworx.info\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rageworx.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1290"}],"version-history":[{"count":0,"href":"https:\/\/rageworx.info\/index.php?rest_route=\/wp\/v2\/posts\/1290\/revisions"}],"wp:attachment":[{"href":"https:\/\/rageworx.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1290"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rageworx.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1290"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rageworx.info\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1290"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}