-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Native multi-frame dicom parsing, multi-value native pixel parsing #7
Conversation
9fa8a26
to
502231a
Compare
502231a
to
8cf48e4
Compare
dicomutil/dicomutil.go
Outdated
defer wg.Done() | ||
i := image.NewGray16(image.Rect(0, 0, 512, 512)) //TODO(suyash): dont assume 512 x 512 | ||
for j := 0; j < len(frame); j++ { | ||
i.SetGray16(j%512, j/512, color.Gray16{Y: uint16(frame[j][0])}) // for now, assume we're not overflowing uint16, assume gray image |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now the utility tool only supports outputting gray images. Color output will be added in future diffs
|
||
pixelsPerFrame := int(rows.MustGetUInt16()) * int(cols.MustGetUInt16()) | ||
|
||
dicomlog.Vprintf(1, "Image size: %d x %d", rows.MustGetUInt16(), cols.MustGetUInt16()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logging lib will be switched out in future diff
@@ -441,7 +454,7 @@ var endOfDataElement = &Element{Tag: dicomtag.Tag{Group: 0x7fff, Element: 0x7fff | |||
// element is a pixel data, or it sees an element defined by options.StopAtTag. | |||
// | |||
// - On successful parsing, it returns non-nil and non-endOfDataElement value. | |||
func ReadElement(d *dicomio.Decoder, options ReadOptions) *Element { | |||
func ReadElement(d *dicomio.Decoder, parsedData *DataSet, options ReadOptions) *Element { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parsing some attributes, namely PixelData
requires information encoded in previously parsed attributes (for example: rows, cols, bits per sample, etc). For exploration purposes, this information was injected into ReadElement
so that it can be used to parse PixelData
into a relatively meaningful form (more than just bytes), but it may also be useful to keep ReadElement
independent of previous elements and do a special second parsing pass on the PixelData
element to put it into a well parsed form...decision will be made after additional consideration and taking stock of this library and any refactors that may be needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
though I find it very appealing for ReadElement
's API to not rely on previous data (though one can always pass in nil
here if not parsing PixelData
elements), that change may have to accompany other refactors that should probably happen in future diffs. #11
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
switch order of parsedData *DataSet, options ReadOptions
so that parsedData=nil
can be the last argument if/when called with nil
@@ -148,14 +150,35 @@ func WriteElement(e *dicomio.Encoder, elem *Element) { | |||
if elem.UndefinedLength { | |||
encodeElementHeader(e, elem.Tag, vr, undefinedLength) | |||
writeBasicOffsetTable(e, image.Offsets) | |||
for _, image := range image.Frames { | |||
for _, image := range image.EncapsulatedFrames { | |||
writeRawItem(e, image) | |||
} | |||
encodeElementHeader(e, dicomtag.SequenceDelimitationItem, "" /*not used*/, 0) | |||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes were made to prevent the writing tests from failing. These take into account the new internal representation of PixelInfo
dicomlog.Vprintf(1, "Pixels Per Frame: %d", pixelsPerFrame) | ||
dicomlog.Vprintf(1, "Number of frames %d", nFrames) | ||
|
||
// Parse the pixels: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider breaking this out into a more abstract function that takes a io.Reader
and nFrames
, pixelsPerFrame
, etc and returns a [][][]int
parsed pixel data.
May also be good to add a pixeldata
package or an image
package that has utility functions and type definitions for specifically parsing pixel data / images. This element.go
is getting a bit large, and likely should live in a package (perhaps a parse
package?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
larger refactors should probably happen in a separate dedicated diff though
@@ -346,18 +348,29 @@ func readRawItem(d *dicomio.Decoder) ([]byte, bool) { | |||
|
|||
// PixelDataInfo is the Element.Value payload for PixelData element. | |||
type PixelDataInfo struct { | |||
Offsets []uint32 // BasicOffsetTable | |||
Frames [][]byte // Parsed images |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
previously wasn't really "frames" because native frames would be parsed into a single frame as raw bytes.
This change:
dicomutil
utility program to parse and write JPG images of native pixel data as well