/// <summary> Constructor for ROI with arbitrary shape /// /// </summary> /// <param name="comp">The component the ROI belongs to /// /// </param> /// <param name="maskPGM">ImgReaderPGM containing the ROI /// </param> public ROI(int comp, ImgReaderPGM maskPGM) { arbShape = true; rect = false; this.comp = comp; this.maskPGM = maskPGM; }
/// <summary> This function generates the ROI mask for one tile-component. /// /// <P> Once the mask is generated in the pixel domain. it is decomposed /// following the same decomposition scheme as the wavelet transform. /// /// </summary> /// <param name="sb">The root of the subband tree used in the decomposition /// /// </param> /// <param name="magbits">The max number of magnitude bits in any code-block /// /// </param> /// <param name="c">component number /// </param> public override void makeMask(Subband sb, int magbits, int c) { int[] mask; // local copy ROI[] rois = this.roi_array; // local copy int i, j, k, r, maxj; // mink, minj removed int lrx, lry; int x, y, w, h; int cx, cy, rad; int wrap; int curScalVal; int tileulx = sb.ulcx; int tileuly = sb.ulcy; int tilew = sb.w; int tileh = sb.h; int lineLen = (tilew > tileh)?tilew:tileh; // Make sure there is a sufficiently large mask buffer if (roiMask[c] == null || (roiMask[c].Length < (tilew * tileh))) { roiMask[c] = new int[tilew * tileh]; mask = roiMask[c]; } else { mask = roiMask[c]; for (i = tilew * tileh - 1; i >= 0; i--) { mask[i] = 0; } } // Make sure there are sufficiently large line buffers if (maskLineLow == null || (maskLineLow.Length < (lineLen + 1) / 2)) { maskLineLow = new int[(lineLen + 1) / 2]; } if (maskLineHigh == null || (maskLineHigh.Length < (lineLen + 1) / 2)) { maskLineHigh = new int[(lineLen + 1) / 2]; } roiInTile = false; // Generate ROIs in pixel domain: for (r = rois.Length - 1; r >= 0; r--) { if (rois[r].comp == c) { curScalVal = magbits; if (rois[r].arbShape) { ImgReaderPGM maskPGM = rois[r].maskPGM; // Local copy if ((src.ImgWidth != maskPGM.ImgWidth) || (src.ImgHeight != maskPGM.ImgHeight)) { throw new System.ArgumentException("Input image and" + " ROI mask must " + "have the same " + "size"); } x = src.ImgULX; y = src.ImgULY; lrx = x + src.ImgWidth - 1; lry = y + src.ImgHeight - 1; if ((x > tileulx + tilew) || (y > tileuly + tileh) || (lrx < tileulx) || (lry < tileuly)) { // Roi not in tile continue; } // Check bounds x -= tileulx; lrx -= tileulx; y -= tileuly; lry -= tileuly; int offx = 0; int offy = 0; if (x < 0) { offx = -x; x = 0; } if (y < 0) { offy = -y; y = 0; } w = (lrx > (tilew - 1))?tilew - x:lrx + 1 - x; h = (lry > (tileh - 1))?tileh - y:lry + 1 - y; // Get shape line by line to reduce memory DataBlkInt srcblk = new DataBlkInt(); int mDcOff = -ImgReaderPGM.DC_OFFSET; int nROIcoeff = 0; int[] src_data; srcblk.ulx = offx; srcblk.w = w; srcblk.h = 1; i = (y + h - 1) * tilew + x + w - 1; maxj = w; wrap = tilew - maxj; for (k = h; k > 0; k--) { srcblk.uly = offy + k - 1; srcblk = (DataBlkInt)maskPGM.getInternCompData(srcblk, 0); src_data = srcblk.DataInt; for (j = maxj; j > 0; j--, i--) { if (src_data[j - 1] != mDcOff) { mask[i] = curScalVal; nROIcoeff++; } } i -= wrap; } if (nROIcoeff != 0) { roiInTile = true; } } else if (rois[r].rect) { // Rectangular ROI x = rois[r].ulx; y = rois[r].uly; lrx = rois[r].w + x - 1; lry = rois[r].h + y - 1; if ((x > tileulx + tilew) || (y > tileuly + tileh) || (lrx < tileulx) || (lry < tileuly)) { // Roi not in tile continue; } roiInTile = true; // Check bounds x -= tileulx; lrx -= tileulx; y -= tileuly; lry -= tileuly; x = (x < 0)?0:x; y = (y < 0)?0:y; w = (lrx > (tilew - 1))?tilew - x:lrx + 1 - x; h = (lry > (tileh - 1))?tileh - y:lry + 1 - y; i = (y + h - 1) * tilew + x + w - 1; maxj = w; wrap = tilew - maxj; for (k = h; k > 0; k--) { for (j = maxj; j > 0; j--, i--) { mask[i] = curScalVal; } i -= wrap; } } else { // Non-rectangular ROI. So far only circular case cx = rois[r].x - tileulx; cy = rois[r].y - tileuly; rad = rois[r].r; i = tileh * tilew - 1; for (k = tileh - 1; k >= 0; k--) { for (j = tilew - 1; j >= 0; j--, i--) { if (((j - cx) * (j - cx) + (k - cy) * (k - cy) < rad * rad)) { mask[i] = curScalVal; roiInTile = true; } } } } } } // If wavelet transform is used if (sb.isNode) { // Decompose the mask according to the subband tree // Calculate size of padded line buffer WaveletFilter vFilter = sb.VerWFilter; WaveletFilter hFilter = sb.HorWFilter; int lvsup = vFilter.SynLowNegSupport + vFilter.SynLowPosSupport; int hvsup = vFilter.SynHighNegSupport + vFilter.SynHighPosSupport; int lhsup = hFilter.SynLowNegSupport + hFilter.SynLowPosSupport; int hhsup = hFilter.SynHighNegSupport + hFilter.SynHighPosSupport; lvsup = (lvsup > hvsup)?lvsup:hvsup; lhsup = (lhsup > hhsup)?lhsup:hhsup; lvsup = (lvsup > lhsup)?lvsup:lhsup; paddedMaskLine = new int[lineLen + lvsup]; if (roiInTile) { decomp(sb, tilew, tileh, c); } } }
/// <summary> This function parses the values given for the ROIs with the argument /// -Rroi. Currently only circular and rectangular ROIs are supported. /// /// <p>A rectangular ROI is indicated by a 'R' followed the coordinates for /// the upper left corner of the ROI and then its width and height.</p> /// /// <p>A circular ROI is indicated by a 'C' followed by the coordinates of /// the circle center and then the radius.</p> /// /// <p>Before the R and C values, the component that are affected by the /// ROI are indicated.</p> /// /// </summary> /// <param name="roiopt">The info on the ROIs /// /// </param> /// <param name="nc">number of components /// /// </param> /// <param name="roiVector">The vcector containing the ROI parsed from the cmd line /// /// </param> /// <returns> The ROIs specified in roiopt /// /// </returns> protected internal static System.Collections.ArrayList parseROIs(System.String roiopt, int nc, System.Collections.ArrayList roiVector) { //ROI[] ROIs; ROI roi; SupportClass.Tokenizer stok; //char tok; int nrOfROIs = 0; //char c; int ulx, uly, w, h, x, y, rad; // comp removed bool[] roiInComp = null; stok = new SupportClass.Tokenizer(roiopt); System.String word; while (stok.HasMoreTokens()) { word = stok.NextToken(); switch (word[0]) { case 'c': // Components specification roiInComp = ModuleSpec.parseIdx(word, nc); break; case 'R': // Rectangular ROI to be read nrOfROIs++; try { word = stok.NextToken(); ulx = (System.Int32.Parse(word)); word = stok.NextToken(); uly = (System.Int32.Parse(word)); word = stok.NextToken(); w = (System.Int32.Parse(word)); word = stok.NextToken(); h = (System.Int32.Parse(word)); } catch (System.FormatException) { throw new System.ArgumentException("Bad parameter for " + "'-Rroi R' option : " + word); } catch (System.ArgumentOutOfRangeException) { throw new System.ArgumentException("Wrong number of " + "parameters for " + "h'-Rroi R' option."); } // If the ROI is component-specific, check which comps. if (roiInComp != null) { for (int i = 0; i < nc; i++) { if (roiInComp[i]) { roi = new ROI(i, ulx, uly, w, h); roiVector.Add(roi); } } } else { // Otherwise add ROI for all components for (int i = 0; i < nc; i++) { roi = new ROI(i, ulx, uly, w, h); roiVector.Add(roi); } } break; case 'C': // Circular ROI to be read nrOfROIs++; try { word = stok.NextToken(); x = (System.Int32.Parse(word)); word = stok.NextToken(); y = (System.Int32.Parse(word)); word = stok.NextToken(); rad = (System.Int32.Parse(word)); } catch (System.FormatException) { throw new System.ArgumentException("Bad parameter for " + "'-Rroi C' option : " + word); } catch (System.ArgumentOutOfRangeException) { throw new System.ArgumentException("Wrong number of " + "parameters for " + "'-Rroi C' option."); } // If the ROI is component-specific, check which comps. if (roiInComp != null) { for (int i = 0; i < nc; i++) { if (roiInComp[i]) { roi = new ROI(i, x, y, rad); roiVector.Add(roi); } } } else { // Otherwise add ROI for all components for (int i = 0; i < nc; i++) { roi = new ROI(i, x, y, rad); roiVector.Add(roi); } } break; case 'A': // ROI wth arbitrary shape nrOfROIs++; System.String filename; ImgReaderPGM maskPGM = null; try { filename = stok.NextToken(); } catch (System.ArgumentOutOfRangeException) { throw new System.ArgumentException("Wrong number of " + "parameters for " + "'-Rroi A' option."); } try { maskPGM = new ImgReaderPGM(filename); } catch (System.IO.IOException) { throw new System.ApplicationException("Cannot read PGM file with ROI"); } // If the ROI is component-specific, check which comps. if (roiInComp != null) { for (int i = 0; i < nc; i++) { if (roiInComp[i]) { roi = new ROI(i, maskPGM); roiVector.Add(roi); } } } else { // Otherwise add ROI for all components for (int i = 0; i < nc; i++) { roi = new ROI(i, maskPGM); roiVector.Add(roi); } } break; default: throw new System.ApplicationException("Bad parameters for ROI nr " + roiVector.Count); } } return(roiVector); }