LRESULT CPreviewClientWindow::OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { CDCHandle dc((HDC) wParam); CRect rc; COLORREF bgCol = RGB(127, 127, 127); if (!m_curOp) { GetClientRect(&rc); dc.FillSolidRect(&rc, bgCol); } else { GetClientRect(&rc); if (rc.right > ImageWidth()) { rc.left = ImageWidth(); dc.FillSolidRect(&rc, bgCol); } GetClientRect(&rc); if (rc.bottom > ImageHeight()) { rc.top = ImageHeight(); rc.right = ImageWidth(); dc.FillSolidRect(&rc, bgCol); } } return 1; }
BOOL CPreviewClientWindow::CursorHitTest(POINT pt) const { const sInt x = pt.x + m_scrlX; const sInt y = pt.y + m_scrlY; return (x >= 0) && (y >= 0) && (x < ImageWidth()) && (y < ImageWidth()); }
void CPreviewClientWindow::UpdateScrollSize(sBool redraw) { if (!IsWindow()) return; frTexture* curTex = getCurrentTex(); if (curTex) { RECT rc; const sInt szx = ImageWidth(); const sInt szy = ImageHeight(); GetClientRect(&rc); m_scrlMaxX = szx - rc.right; if (m_scrlMaxX < 0) m_scrlMaxX = 0; m_scrlMaxY = szy - rc.bottom; if (m_scrlMaxY < 0) m_scrlMaxY = 0; m_scrlX = clamp(m_scrlX, 0, m_scrlMaxX); m_scrlY = clamp(m_scrlY, 0, m_scrlMaxY); } else { m_scrlX = m_scrlY = 0; m_scrlMaxX = m_scrlMaxY = 0; } if (redraw) { Invalidate(); UpdateWindow(); } }
/*************************************************************** *函数名称: TransSobelAnalysis * * 参数: IMG 图像 * * * 返回值: 不存在斑点 true, * 存在斑点 false * * 功能: 在指定的区域内采用sobel滤波+ * 斑点分析的方法检测是否存在斑点 * ****************************************************************/ bool CapsuleProc::TransSobelAnalysis(IMG image) { IMG copyImage = 0; CreateDuplicateImage (image, copyImage); HorizonExtend::Extend(copyImage); long width = ImageWidth(copyImage); long height= ImageHeight(copyImage); TRect2D<long> roi = TRect2D<long>(TPoint2D<long>(0,0), width, height); roi.Expand(-2, -2); bool success = false; IMG imageROI= NULL; CreateImageMap( copyImage, roi.x0(), roi.y0(), roi.x1(), roi.y1(), roi.Width(), roi.Height(), imageROI); if(IsImage(imageROI)) { IMG imageSobel = 0; FilterSobelVertical(imageROI, FM_5x5, imageSobel); success = RectBlackBlob ( imageSobel, m_segmentParam.dynWndSize, m_segmentParam.dynThres - 2, m_segmentParam.blobSize, FBLOB_BORDER_ALL, -1, 4); m_sortObserver.ObserverIMG(SortObserver::MSobel, copyImage); m_sortObserver.ObserverIMG(SortObserver::CSobel, imageSobel); ReleaseImage(imageSobel); } ReleaseImage(imageROI); ReleaseImage(copyImage); return success; }
// Recognizes a word or group of words, converting to WERD_RES in *words. // Analogous to classify_word_pass1, but can handle a group of words as well. void Tesseract::LSTMRecognizeWord(const BLOCK& block, ROW *row, WERD_RES *word, PointerVector<WERD_RES>* words) { TBOX word_box = word->word->bounding_box(); // Get the word image - no frills. if (tessedit_pageseg_mode == PSM_SINGLE_WORD || tessedit_pageseg_mode == PSM_RAW_LINE) { // In single word mode, use the whole image without any other row/word // interpretation. word_box = TBOX(0, 0, ImageWidth(), ImageHeight()); } else { float baseline = row->base_line((word_box.left() + word_box.right()) / 2); if (baseline + row->descenders() < word_box.bottom()) word_box.set_bottom(baseline + row->descenders()); if (baseline + row->x_height() + row->ascenders() > word_box.top()) word_box.set_top(baseline + row->x_height() + row->ascenders()); } ImageData* im_data = GetRectImage(word_box, block, kImagePadding, &word_box); if (im_data == NULL) return; lstm_recognizer_->RecognizeLine(*im_data, true, classify_debug_level > 0, kWorstDictCertainty / kCertaintyScale, lstm_use_matrix, &unicharset, word_box, 2.0, false, words); delete im_data; SearchWords(words); }
/*************************************************************** * 函数名称: TransDoubleJudge * * 参数: IMG 子图像 * size_t 半径 * * 返回值: 存在 true * 不存在 false * * * 功能: 判断是否存在两个边界 * * ****************************************************************/ bool CapsuleProc::TransDoubleJudge ( IMG &subImage, const size_t radius) { const long areaWidth = 20; long centreX = ImageWidth(subImage)/2; long centreY = ImageHeight(subImage)/2; TArea area; area.X0 = centreX -areaWidth; area.X2 = centreX -areaWidth; area.X1 = centreX +areaWidth; area.Y0 = centreY; area.Y2 = centreY-radius; area.Y1 = centreY; TEdgeResult tr; CFindFirstEdge ( subImage, 0, m_segmentParam.edgeDensity, area, m_segmentParam.edgeThres, FALSE, tr); area.X0 = centreX -areaWidth; area.X2 = centreX -areaWidth; area.X1 = centreX +areaWidth; area.Y0 = centreY; area.Y2 = centreY+radius; area.Y1 = centreY; TEdgeResult downEdge; CFindFirstEdge ( subImage, 0, m_segmentParam.edgeDensity, area, m_segmentParam.edgeThres, FALSE, downEdge); if ((tr.y == 0.f)||(downEdge.y == 0.f)) { return true; } else { return false; } }
bool CapsuleProc::BlobAnalysis( IMG image, long upEdgeY, long downEdgeY, long wndSize, long dynThres, long blobSize) { long x0 = 0, y0 =0, dx = 0, dy = 0; ProfileBlob(image, ImageWidth(image)/2, m_cvbBlob); FBlobGetBoundingBox(m_cvbBlob, 0, x0, y0, dx, dy); y0 = 0; dy = ImageHeight(image) - 1; //中间部分 TRect2D<long> roi(x0, upEdgeY, x0+dx, downEdgeY); roi.Expand (-10, -6); if(false == RectangleBlob(image, roi, wndSize, dynThres, blobSize, FBLOB_BORDER_ALL, -1, -1, true)) { return false; } if (upEdgeY - y0> (y0 + dy) - downEdgeY) { roi = TRect2D<long>(x0, y0, x0+dx, upEdgeY-15); if(false == RectangleBlob(image, roi, wndSize, dynThres, blobSize, FBLOB_BORDER_ALL)) { return false; } roi = TRect2D<long>(x0, downEdgeY+15, x0+dx, y0+dy); if(false == RectangleBlob(image, roi, wndSize, dynThres+5, blobSize, FBLOB_BORDER_ALL)) { return false; } } else { roi= TRect2D<long>(x0, y0, x0+dx, upEdgeY-15); if(false == RectangleBlob(image, roi, wndSize, dynThres+5, blobSize, FBLOB_BORDER_ALL)) { return false; } roi = TRect2D<long>(x0, downEdgeY+15, x0+dx, y0+dy); if(false == RectangleBlob(image, roi, wndSize, dynThres, blobSize, FBLOB_BORDER_ALL)) { return false; } } if (upEdgeY - y0> (y0 + dy) - downEdgeY) { roi = TRect2D<long>(x0, y0 + (dx/2), x0+dx, upEdgeY-15); } else { roi = TRect2D<long>(x0, downEdgeY+15, x0+dx, y0+dy - (dx/2)); } roi.Expand (-10, -6); if(false == RectangleBlob(image, roi, wndSize, dynThres, blobSize, FBLOB_BORDER_NONE, -1, -1, true)) { return false; } return true; }
void Tesseract::reject_edge_blobs(WERD_RES *word) { TBOX word_box = word->word->bounding_box(); // Use the box_word as it is already denormed back to image coordinates. int blobcount = word->box_word->length(); if (word_box.left() < tessedit_image_border || word_box.bottom() < tessedit_image_border || word_box.right() + tessedit_image_border > ImageWidth() - 1 || word_box.top() + tessedit_image_border > ImageHeight() - 1) { ASSERT_HOST(word->reject_map.length() == blobcount); for (int blobindex = 0; blobindex < blobcount; blobindex++) { TBOX blob_box = word->box_word->BlobBox(blobindex); if (blob_box.left() < tessedit_image_border || blob_box.bottom() < tessedit_image_border || blob_box.right() + tessedit_image_border > ImageWidth() - 1 || blob_box.top() + tessedit_image_border > ImageHeight() - 1) { word->reject_map[blobindex].setrej_edge_char(); // Close to edge } } } }
/*************************************************************** *函数名称: ShrinkVertical * * 参数: image 检测图像 * shrinkNum 纵向缩减的数值 *返回值: 成功 true * 失败 false * * 功能: 对胶囊的图像进行纵向的缩减 ****************************************************************/ bool CapsuleProc::ShrinkVertical( IMG image, const size_t shrinkNum) { unsigned char *pImageBit = NULL; PVPAT VPA = NULL; GetImageVPA (image, 0, (void**)&pImageBit, &VPA); const size_t imageWidth = ImageWidth (image); const size_t imageHeight = ImageHeight(image); const size_t halfHeight = imageHeight/2; if (halfHeight < shrinkNum) { return false; } const unsigned char cstVal = 127; unsigned char* curVal = 0; for(size_t i = 0; i < imageWidth; ++i) { for(size_t j = 0; j <= halfHeight; ++j) { curVal = (VPA[i].XEntry + pImageBit + VPA[j].YEntry); if (cstVal == *curVal) { *curVal = 0; } else if (0 == *curVal) { continue; } else { for(size_t eroCount = 0; eroCount < shrinkNum; ++eroCount) { *(VPA[i].XEntry + pImageBit + VPA[eroCount + j].YEntry) = 0; } break; } } for(size_t j = imageHeight - 1; j >= halfHeight; --j) { curVal = (VPA[i].XEntry + pImageBit + VPA[j].YEntry); if (cstVal == *curVal) { *curVal = 0; } else if (0 == *curVal) { continue; } else { for(size_t eroCount = 0; eroCount < shrinkNum; ++eroCount) { *(VPA[i].XEntry + pImageBit + VPA[ j-eroCount].YEntry) = 0; } break; } } } return true; }
bool CapsuleProc::ShrinkHorizontal( IMG image, const size_t shrinkNum) { unsigned char *pImageBit = NULL; PVPAT VPA = NULL; GetImageVPA (image, 0, (void**)&pImageBit, &VPA); const size_t imageWidth = ImageWidth (image); const size_t imageHeight = ImageHeight(image); const size_t halfWidth = imageWidth / 2; const unsigned char cstVal = 127; unsigned char* curVal = 0; if (halfWidth < shrinkNum) { return false; } for(size_t veCo = 0; veCo < imageHeight; ++veCo) { for(size_t i = 0; i <= halfWidth; ++i) { curVal = (VPA[veCo].YEntry + pImageBit + VPA[i].XEntry); if ( cstVal == *curVal) { *curVal = 0; } else if(0 == *curVal) { continue; } else { for(size_t j = 0; j < shrinkNum; ++j) { *(VPA[veCo].YEntry + pImageBit + VPA[j + i].XEntry) = 0; } break; } } for(size_t i = imageWidth; i >= halfWidth; --i) { curVal = (VPA[veCo].YEntry + pImageBit + VPA[i].XEntry); if (cstVal == *curVal) { *curVal = 0; } else if(0 == *curVal) { continue; } else { for(size_t j = 0; j < shrinkNum; ++j) { *(VPA[veCo].YEntry + pImageBit + VPA[i - j].XEntry) = 0; } break; } } } return true; }
/*************************************************************** *函数名称: FindUpDownEdge * * 参数: image 子图像 * density 边沿检测的密度 * threshold 阈值 * upPos 上边沿 * downPos 下边沿 * * 返回值: 成功 true * 失败 false * * * 功能: 得到胶囊套合区的上下边沿的坐标 ****************************************************************/ bool CapsuleProc::FindUpDownEdge( IMG image, long density,double threshold, long &upPos, long &downPos) { long overX =0, overY =0; FindOverlapCenter(image, overX, overY); long roiWidth = ImageWidth(image)/2; long roiHeight = ImageHeight(image)/3; TArea areaUp = CreateTArea(overX -roiWidth/2, overY, roiWidth, roiHeight); long yUp = FindFirstEdgeY(image, areaUp, density,threshold); TArea areaDown = CreateTArea(overX -roiWidth/2, overY, roiWidth, -roiHeight); long yDown = FindFirstEdgeY(image, areaDown, density, threshold); upPos = yUp; downPos = yDown; return ((upPos != -1) && (downPos != -1)); }
bool HorizonExtend::Extend(IMG image) { unsigned char* pImgBase = NULL; PVPAT VPAT = NULL; GetImageVPA (image, 0, (LPVOID *)&pImgBase, (PVPAT*)&VPAT); long width = ImageWidth (image); long height = ImageHeight (image); for (long y=0; y< height; ++y) { unsigned char* pLineAddr = pImgBase + VPAT[y].YEntry; TwoEndInfo endInfo = GetEndInfo(pLineAddr, VPAT, width); SetPixelValue(pLineAddr, VPAT, width, endInfo); } return true; }
bool CapsuleProc::FindOverlapCenter(IMG rawSubImg, long& centerX, long& centerY) { if(!IsImage(rawSubImg)) { centerX = -1; centerY = -1; return false; } long width = ImageWidth (rawSubImg); long height = ImageHeight(rawSubImg); long xc = width/2; long yc0 = height/2 - height/8; long yc1 = height/2 + height/8; double upMean = 0; double downMean = 0; long offsetX = width/4; long offsetY = 5; TArea upArea = CreateTArea(xc - offsetX, yc0 + offsetY, 2*offsetX, 2*offsetY); LMSetImage (m_lightMeter, rawSubImg); LMSetProcessFlag (m_lightMeter, 0, TRUE); LMSetArea (m_lightMeter, 0, upArea); LMExecute (m_lightMeter); LMGetStatisticMean (m_lightMeter, 0, &upMean); TArea downArea = CreateTArea(xc - offsetX, yc1 - offsetY, 2*offsetX, -2*offsetY); LMSetImage (m_lightMeter, rawSubImg); LMSetProcessFlag (m_lightMeter, 0, TRUE); LMSetArea (m_lightMeter, 0, downArea); LMExecute (m_lightMeter); LMGetStatisticMean (m_lightMeter, 0, &downMean); centerX = xc; centerY = upMean <= downMean ? yc0 : yc1; return true; }
bool CapsuleProc::SobelAnalysis(IMG image) { IMG copyImage = 0; CreateDuplicateImage (image, copyImage); HorizonExtend::Extend(copyImage); long width = ImageWidth(copyImage); long height= ImageHeight(copyImage); TRect2D<long> roi = TRect2D<long>(TPoint2D<long>(0,0), width, height); roi.Expand(-2, -2); bool success = RectSobelBlob( copyImage, roi, m_segmentParam.dynWndSize, m_segmentParam.dynThres, m_segmentParam.blobSize, FBLOB_BORDER_ALL); ReleaseImage(copyImage); return success; }
string Driver::GetNextTextElement(string& text,TextStyle& style,int& w,int& h,int maxwidth) { size_t n=0; string ret; if(text=="") return ""; // Return blank space as is. while(n < text.length() && IsSpace(text[n]) && text[n]!='\n') n++; if(n) { } // Get a tag if found. else if(text[0]=='{') { while(n < text.length()) if(text[n]=='}') { n++; break; } else n++; } // Cut from the next word break. else { while(n < text.length()) if(text[n]=='.' || text[n]==',' || text[n]==';' || text[n]==':' || text[n]=='!' || text[n]=='?' || text[n]=='\n' || text[n]=='-' || text[n]=='/') { n++; break; } else if(text[n]=='{' || IsSpace(text[n])) break; else n++; } // Extract the next element from the text. if(n==text.length()) { ret=text; text=""; } else { ret=text.substr(0,n); text=text.substr(n); } w=0; h=0; // Compute the size for normal text. if(ret[0]!='{') { w=TextWidth(style.font,style.pointsize,ret); // Shorten the word if it does not fit. while(w > maxwidth && ret.length()) { w-=TextWidth(style.font,style.pointsize,ret.substr(ret.length()-1,1)); text=ret.substr(ret.length()-1,1)+text; ret=ret.substr(0,ret.length()-1); } h=TextHeight(style.font,style.pointsize,ret); } // Compute the size for tags. else if(ret=="{|}") { w=3; h=TextHeight(style.font,style.pointsize,"|"); } else if(ret=="{hr}") { w=w-2*style.margin; h=1; } else if(ret=="{lb}") { w=TextWidth(style.font,style.pointsize,"{"); h=TextHeight(style.font,style.pointsize,"{"); } else if(ret=="{rb}") { w=TextWidth(style.font,style.pointsize,"}"); h=TextHeight(style.font,style.pointsize,"}"); } else if(inlineimage.find(ret)!=inlineimage.end()) { w=ImageWidth(inlineimage[ret]); h=ImageHeight(inlineimage[ret]); } else if(ret.substr(0,3)=="{sz" && ret.substr(ret.length()-1,1)=="}") { int sz=atoi(ret.substr(3,ret.length()-4).c_str()); if(sz < 6) sz=6; else if(sz > 255) sz=255; style.pointsize=sz; } else if(ret.substr(0,5)=="{font" && ret.substr(ret.length()-1,1)=="}") { int n=atoi(ret.substr(5,ret.length()-6).c_str()); if(n < 0) n=0; else if(n > 6) n=6; style.font=n; } else if(ret.substr(0,5)=="{card" && ret.substr(ret.length()-1,1)=="}") { int n=atoi(ret.substr(5,ret.length()-6).c_str()); string name="_unknown_"; if(n >= 0 && n < Database::cards.Cards()) name=Database::cards.Name(n); w=TextWidth(style.font,style.pointsize,name); h=TextHeight(style.font,style.pointsize,name); } else if(ret=="{red}") style.color=RED; else if(ret=="{green}") style.color=GREEN; else if(ret=="{black}") style.color=BLACK; else if(ret=="{blue}") style.color=BLUE; else if(ret=="{yellow}") style.color=YELLOW; else if(ret=="{white}") style.color=WHITE; else if(ret=="{brown}") style.color=Color(149,79,29); else if(ret=="{gold}") style.color=Color(205,173,0); else if(ret=="{gray}") style.color=Color(77,77,77); else if(ret=="{magenta}") style.color=Color(205,0,205); else if(ret=="{orange}") style.color=Color(255,127,0); else if(ret=="{cyan}") style.color=Color(4,197,204); else if(ret=="{shadow}") style.shadow=true; else if(ret=="{noshadow}") style.shadow=false; else if(ret=="{reset}") { bool old=style.shadow; style=TextStyle(); style.shadow=old; } else { int r=atoi(ret.substr(1).c_str()); int g=-1; int b=-1; if(r>0 || ret.substr(1,2)=="0,") { for(size_t n=0; n < ret.length(); n++) { if(ret[n]==',') { n++; g=atoi(ret.substr(n).c_str()); for(; n < ret.length(); n++) if(ret[n]==',') { b=atoi(ret.substr(n+1).c_str()); break; } break; } } if(r>=0 && g>=0 && b>=0 && r<256 && g<256 && b<256) { style.color.r=r; style.color.g=g; style.color.b=b; } } } return ret; }
void WSMSGridder::Invert() { MSData* msDataVector = new MSData[MeasurementSetCount()]; _hasFrequencies = false; for(size_t i=0; i!=MeasurementSetCount(); ++i) initializeMeasurementSet(i, msDataVector[i]); double minW = msDataVector[0].minW; double maxW = msDataVector[0].maxW; for(size_t i=1; i!=MeasurementSetCount(); ++i) { if(msDataVector[i].minW < minW) minW = msDataVector[i].minW; if(msDataVector[i].maxW > maxW) maxW = msDataVector[i].maxW; } _gridder = std::unique_ptr<WStackingGridder>(new WStackingGridder(_actualInversionWidth, _actualInversionHeight, _actualPixelSizeX, _actualPixelSizeY, _cpuCount, _imageBufferAllocator, AntialiasingKernelSize(), OverSamplingFactor())); _gridder->SetGridMode(_gridMode); if(_denormalPhaseCentre) _gridder->SetDenormalPhaseCentre(_phaseCentreDL, _phaseCentreDM); _gridder->SetIsComplex(IsComplex()); //_imager->SetImageConjugatePart(Polarization() == Polarization::YX && IsComplex()); _gridder->PrepareWLayers(WGridSize(), double(_memSize)*(7.0/10.0), minW, maxW); if(Verbose()) { for(size_t i=0; i!=MeasurementSetCount(); ++i) countSamplesPerLayer(msDataVector[i]); } _totalWeight = 0.0; for(size_t pass=0; pass!=_gridder->NPasses(); ++pass) { std::cout << "Gridding pass " << pass << "... "; if(Verbose()) std::cout << '\n'; else std::cout << std::flush; _inversionWorkLane.reset(new ao::lane<InversionWorkItem>(2048)); _gridder->StartInversionPass(pass); for(size_t i=0; i!=MeasurementSetCount(); ++i) { _inversionWorkLane->clear(); MSData& msData = msDataVector[i]; const MultiBandData selectedBand(msData.SelectedBand()); boost::thread thread(&WSMSGridder::workThreadParallel, this, &selectedBand); gridMeasurementSet(msData); _inversionWorkLane->write_end(); thread.join(); } _inversionWorkLane.reset(); std::cout << "Fourier transforms...\n"; _gridder->FinishInversionPass(); } if(Verbose()) { size_t totalRowsRead = 0, totalMatchingRows = 0; for(size_t i=0; i!=MeasurementSetCount(); ++i) { totalRowsRead += msDataVector[i].totalRowsProcessed; totalMatchingRows += msDataVector[i].matchingRows; } std::cout << "Total rows read: " << totalRowsRead; if(totalMatchingRows != 0) std::cout << " (overhead: " << std::max(0.0, round(totalRowsRead * 100.0 / totalMatchingRows - 100.0)) << "%)"; std::cout << '\n'; } if(NormalizeForWeighting()) _gridder->FinalizeImage(1.0/_totalWeight, false); else { std::cout << "Not dividing by normalization factor of " << _totalWeight << ".\n"; _gridder->FinalizeImage(1.0, true); } if(ImageWidth()!=_actualInversionWidth || ImageHeight()!=_actualInversionHeight) { FFTResampler resampler(_actualInversionWidth, _actualInversionHeight, ImageWidth(), ImageHeight(), _cpuCount); if(IsComplex()) { double *resizedReal = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); double *resizedImag = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); resampler.Start(); resampler.AddTask(_gridder->RealImage(), resizedReal); resampler.AddTask(_gridder->ImaginaryImage(), resizedImag); resampler.Finish(); _gridder->ReplaceRealImageBuffer(resizedReal); _gridder->ReplaceImaginaryImageBuffer(resizedImag); } else { double *resized = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); resampler.RunSingle(_gridder->RealImage(), resized); _gridder->ReplaceRealImageBuffer(resized); } } delete[] msDataVector; }
void WSMSGridder::initializeMeasurementSet(size_t msIndex, WSMSGridder::MSData& msData) { MSProvider& msProvider = MeasurementSet(msIndex); msData.msProvider = &msProvider; casacore::MeasurementSet& ms(msProvider.MS()); if(ms.nrow() == 0) throw std::runtime_error("Table has no rows (no data)"); /** * Read some meta data from the measurement set */ casacore::MSAntenna aTable = ms.antenna(); size_t antennaCount = aTable.nrow(); if(antennaCount == 0) throw std::runtime_error("No antennae in set"); casacore::MPosition::ROScalarColumn antPosColumn(aTable, aTable.columnName(casacore::MSAntennaEnums::POSITION)); casacore::MPosition ant1Pos = antPosColumn(0); msData.bandData = MultiBandData(ms.spectralWindow(), ms.dataDescription()); if(Selection(msIndex).HasChannelRange()) { msData.startChannel = Selection(msIndex).ChannelRangeStart(); msData.endChannel = Selection(msIndex).ChannelRangeEnd(); std::cout << "Selected channels: " << msData.startChannel << '-' << msData.endChannel << '\n'; const BandData& firstBand = msData.bandData.FirstBand(); if(msData.startChannel >= firstBand.ChannelCount() || msData.endChannel > firstBand.ChannelCount() || msData.startChannel == msData.endChannel) { std::ostringstream str; str << "An invalid channel range was specified! Measurement set only has " << firstBand.ChannelCount() << " channels, requested imaging range is " << msData.startChannel << " -- " << msData.endChannel << '.'; throw std::runtime_error(str.str()); } } else { msData.startChannel = 0; msData.endChannel = msData.bandData.FirstBand().ChannelCount(); } casacore::MEpoch::ROScalarColumn timeColumn(ms, ms.columnName(casacore::MSMainEnums::TIME)); const MultiBandData selectedBand = msData.SelectedBand(); if(_hasFrequencies) { _freqLow = std::min(_freqLow, selectedBand.LowestFrequency()); _freqHigh = std::max(_freqHigh, selectedBand.HighestFrequency()); _bandStart = std::min(_bandStart, selectedBand.BandStart()); _bandEnd = std::max(_bandEnd, selectedBand.BandEnd()); _startTime = std::min(_startTime, msProvider.StartTime()); } else { _freqLow = selectedBand.LowestFrequency(); _freqHigh = selectedBand.HighestFrequency(); _bandStart = selectedBand.BandStart(); _bandEnd = selectedBand.BandEnd(); _startTime = msProvider.StartTime(); _hasFrequencies = true; } casacore::MSField fTable(ms.field()); casacore::MDirection::ROScalarColumn phaseDirColumn(fTable, fTable.columnName(casacore::MSFieldEnums::PHASE_DIR)); casacore::MDirection phaseDir = phaseDirColumn(Selection(msIndex).FieldId()); casacore::MEpoch curtime = timeColumn(0); casacore::MeasFrame frame(ant1Pos, curtime); casacore::MDirection::Ref j2000Ref(casacore::MDirection::J2000, frame); casacore::MDirection j2000 = casacore::MDirection::Convert(phaseDir, j2000Ref)(); casacore::Vector<casacore::Double> j2000Val = j2000.getValue().get(); _phaseCentreRA = j2000Val[0]; _phaseCentreDec = j2000Val[1]; if(fTable.keywordSet().isDefined("WSCLEAN_DL")) _phaseCentreDL = fTable.keywordSet().asDouble(casacore::RecordFieldId("WSCLEAN_DL")); else _phaseCentreDL = 0.0; if(fTable.keywordSet().isDefined("WSCLEAN_DM")) _phaseCentreDM = fTable.keywordSet().asDouble(casacore::RecordFieldId("WSCLEAN_DM")); else _phaseCentreDM = 0.0; _denormalPhaseCentre = _phaseCentreDL != 0.0 || _phaseCentreDM != 0.0; if(_denormalPhaseCentre) std::cout << "Set has denormal phase centre: dl=" << _phaseCentreDL << ", dm=" << _phaseCentreDM << '\n'; std::cout << "Determining min and max w & theoretical beam size... " << std::flush; msData.maxW = 0.0; msData.minW = 1e100; double maxBaseline = 0.0; std::vector<float> weightArray(selectedBand.MaxChannels()); msProvider.Reset(); while(msProvider.CurrentRowAvailable()) { size_t dataDescId; double uInM, vInM, wInM; msProvider.ReadMeta(uInM, vInM, wInM, dataDescId); const BandData& curBand = selectedBand[dataDescId]; double wHi = fabs(wInM / curBand.SmallestWavelength()); double wLo = fabs(wInM / curBand.LongestWavelength()); double baselineInM = sqrt(uInM*uInM + vInM*vInM + wInM*wInM); double halfWidth = 0.5*ImageWidth(), halfHeight = 0.5*ImageHeight(); if(wHi > msData.maxW || wLo < msData.minW || baselineInM / curBand.SmallestWavelength() > maxBaseline) { msProvider.ReadWeights(weightArray.data()); const float* weightPtr = weightArray.data(); for(size_t ch=0; ch!=curBand.ChannelCount(); ++ch) { if(*weightPtr != 0.0) { const double wavelength = curBand.ChannelWavelength(ch); double uInL = uInM/wavelength, vInL = vInM/wavelength, wInL = wInM/wavelength, x = uInL * PixelSizeX() * ImageWidth(), y = vInL * PixelSizeY() * ImageHeight(), imagingWeight = this->PrecalculatedWeightInfo()->GetWeight(uInL, vInL); if(imagingWeight != 0.0) { if(floor(x) > -halfWidth && ceil(x) < halfWidth && floor(y) > -halfHeight && ceil(y) < halfHeight) { msData.maxW = std::max(msData.maxW, fabs(wInL)); msData.minW = std::min(msData.minW, fabs(wInL)); maxBaseline = std::max(maxBaseline, baselineInM / wavelength); } } } ++weightPtr; } } msProvider.NextRow(); } if(msData.minW == 1e100) { msData.minW = 0.0; msData.maxW = 0.0; } _beamSize = 1.0 / maxBaseline; std::cout << "DONE (w=[" << msData.minW << ":" << msData.maxW << "] lambdas, maxuvw=" << maxBaseline << " lambda, beam=" << Angle::ToNiceString(_beamSize) << ")\n"; if(HasWLimit()) { msData.maxW *= (1.0 - WLimit()); if(msData.maxW < msData.minW) msData.maxW = msData.minW; } _actualInversionWidth = ImageWidth(); _actualInversionHeight = ImageHeight(); _actualPixelSizeX = PixelSizeX(); _actualPixelSizeY = PixelSizeY(); if(SmallInversion()) { double totalWidth = _actualInversionWidth * _actualPixelSizeX, totalHeight = _actualInversionHeight * _actualPixelSizeY; // Calc min res based on Nyquist sampling rate size_t minResX = size_t(ceil(totalWidth*2 / _beamSize)); if(minResX%4 != 0) minResX += 4 - (minResX%4); size_t minResY = size_t(ceil(totalHeight*2 / _beamSize)); if(minResY%4 != 0) minResY += 4 - (minResY%4); if(minResX < _actualInversionWidth || minResY < _actualInversionHeight) { _actualInversionWidth = std::max(std::min(minResX, _actualInversionWidth), size_t(32)); _actualInversionHeight = std::max(std::min(minResY, _actualInversionHeight), size_t(32)); std::cout << "Setting small inversion image size of " << _actualInversionWidth << " x " << _actualInversionHeight << "\n"; _actualPixelSizeX = totalWidth / _actualInversionWidth; _actualPixelSizeY = totalHeight / _actualInversionHeight; } else { std::cout << "Small inversion enabled, but inversion resolution already smaller than beam size: not using optimization.\n"; } } if(Verbose() || !HasWGridSize()) { double maxL = ImageWidth() * PixelSizeX() * 0.5 + fabs(_phaseCentreDL), maxM = ImageHeight() * PixelSizeY() * 0.5 + fabs(_phaseCentreDM), lmSq = maxL * maxL + maxM * maxM; double cMinW = IsComplex() ? -msData.maxW : msData.minW; double radiansForAllLayers; if(lmSq < 1.0) radiansForAllLayers = 2 * M_PI * (msData.maxW - cMinW) * (1.0 - sqrt(1.0 - lmSq)); else radiansForAllLayers = 2 * M_PI * (msData.maxW - cMinW); size_t suggestedGridSize = size_t(ceil(radiansForAllLayers)); if(suggestedGridSize == 0) suggestedGridSize = 1; if(suggestedGridSize < _cpuCount) { // When nwlayers is lower than the nr of cores, we cannot parallellize well. // However, we don't want extra w-layers if we are low on mem, as that might slow down the process double memoryRequired = double(_cpuCount) * double(sizeof(double))*double(_actualInversionWidth*_actualInversionHeight); if(4.0 * memoryRequired < double(_memSize)) { std::cout << "The theoretically suggested number of w-layers (" << suggestedGridSize << ") is less than the number of availables\n" "cores (" << _cpuCount << "). Changing suggested number of w-layers to " << _cpuCount << ".\n"; suggestedGridSize = _cpuCount; } else { std::cout << "The theoretically suggested number of w-layers (" << suggestedGridSize << ") is less than the number of availables\n" "cores (" << _cpuCount << "), but there is not enough memory available to increase the number of w-layers.\n" "Not all cores can be used efficiently.\n"; } } if(Verbose()) std::cout << "Suggested number of w-layers: " << ceil(suggestedGridSize) << '\n'; if(!HasWGridSize()) SetWGridSize(suggestedGridSize); } }
void WSMSGridder::Predict(double* real, double* imaginary) { if(imaginary==0 && IsComplex()) throw std::runtime_error("Missing imaginary in complex prediction"); if(imaginary!=0 && !IsComplex()) throw std::runtime_error("Imaginary specified in non-complex prediction"); MSData* msDataVector = new MSData[MeasurementSetCount()]; _hasFrequencies = false; for(size_t i=0; i!=MeasurementSetCount(); ++i) initializeMeasurementSet(i, msDataVector[i]); double minW = msDataVector[0].minW; double maxW = msDataVector[0].maxW; for(size_t i=1; i!=MeasurementSetCount(); ++i) { if(msDataVector[i].minW < minW) minW = msDataVector[i].minW; if(msDataVector[i].maxW > maxW) maxW = msDataVector[i].maxW; } _gridder = std::unique_ptr<WStackingGridder>(new WStackingGridder(_actualInversionWidth, _actualInversionHeight, _actualPixelSizeX, _actualPixelSizeY, _cpuCount, _imageBufferAllocator, AntialiasingKernelSize(), OverSamplingFactor())); _gridder->SetGridMode(_gridMode); if(_denormalPhaseCentre) _gridder->SetDenormalPhaseCentre(_phaseCentreDL, _phaseCentreDM); _gridder->SetIsComplex(IsComplex()); //_imager->SetImageConjugatePart(Polarization() == Polarization::YX && IsComplex()); _gridder->PrepareWLayers(WGridSize(), double(_memSize)*(7.0/10.0), minW, maxW); if(Verbose()) { for(size_t i=0; i!=MeasurementSetCount(); ++i) countSamplesPerLayer(msDataVector[i]); } double *resizedReal = 0, *resizedImag = 0; if(ImageWidth()!=_actualInversionWidth || ImageHeight()!=_actualInversionHeight) { FFTResampler resampler(ImageWidth(), ImageHeight(), _actualInversionWidth, _actualInversionHeight, _cpuCount); if(imaginary == 0) { resizedReal = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); resampler.RunSingle(real, resizedReal); real = resizedReal; } else { resizedReal = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); resizedImag = _imageBufferAllocator->Allocate(ImageWidth() * ImageHeight()); resampler.Start(); resampler.AddTask(real, resizedReal); resampler.AddTask(imaginary, resizedImag); resampler.Finish(); real = resizedReal; imaginary = resizedImag; } } for(size_t pass=0; pass!=_gridder->NPasses(); ++pass) { std::cout << "Fourier transforms for pass " << pass << "... "; if(Verbose()) std::cout << '\n'; else std::cout << std::flush; if(imaginary == 0) _gridder->InitializePrediction(real); else _gridder->InitializePrediction(real, imaginary); _gridder->StartPredictionPass(pass); std::cout << "Predicting...\n"; for(size_t i=0; i!=MeasurementSetCount(); ++i) predictMeasurementSet(msDataVector[i]); } if(ImageWidth()!=_actualInversionWidth || ImageHeight()!=_actualInversionHeight) { _imageBufferAllocator->Free(resizedReal); _imageBufferAllocator->Free(resizedImag); } size_t totalRowsWritten = 0, totalMatchingRows = 0; for(size_t i=0; i!=MeasurementSetCount(); ++i) { totalRowsWritten += msDataVector[i].totalRowsProcessed; totalMatchingRows += msDataVector[i].matchingRows; } std::cout << "Total rows written: " << totalRowsWritten; if(totalMatchingRows != 0) std::cout << " (overhead: " << std::max(0.0, round(totalRowsWritten * 100.0 / totalMatchingRows - 100.0)) << "%)"; std::cout << '\n'; delete[] msDataVector; }
/*************************************************************** *函数名称: TransProcess * * 参数: 无 * * * 返回值: unsigned int 处理结果 * * * 功能: 透明胶囊处理 * * ****************************************************************/ unsigned int CapsuleProc::TransProcess( WORKMODE mode ) { TTimeDiff td; td.Reset(); m_curData.Clear(); m_sortResult.NewPeriod(); m_sortObserver.NewPeriod(SortObserver::Mono); TImgDim dim = Dimension(); if (!m_transRemain.RemainCapsule(m_rawImage, dim, m_profileImage, m_remainParam, TTransRemain::TRANSMODE)) { OutputDebugString("RemainCapsule Failed!"); return 0; } m_sortObserver.ObserverIMG (SortObserver::MAll, m_cvbProfileImg); long profileBlobCount = 0; long minWidth = 1 + m_capsuleParam.capsuleDim.width/8; ProfileBlob (m_cvbProfileImg, minWidth, m_profileBlob); FBlobGetNumBlobs(m_profileBlob, profileBlobCount); int counter = 0; for(int i = 0; i < profileBlobCount; i++) { IMG proSubRot = NULL; size_t posIndex = 0; if(TransRotateIMG(i, m_profileBlob, m_cvbProfileImg, proSubRot, posIndex)) { if(posIndex ==0 || posIndex == 2) { counter++; } m_sortObserver.ObserverIMG(SortObserver::MSub, proSubRot); const long width = ImageWidth (proSubRot); const long height= ImageHeight(proSubRot); m_curData.WidthAndHeight(width, height); //all short if( IsCapsuleShort( height, width, m_capsuleParam.capsuleDim.height, m_capsuleParam.capsuleDim.tolerance)) { if (REALTIME == mode) { m_sortResult.SetResult(SortResult::ShortErr, posIndex); OutputDebugString("Capsule Short!"); ReleaseImage(proSubRot); continue; } } if (false == TransDoubleJudge(proSubRot, width/2)) { if (REALTIME == mode) { m_sortResult.SetResult(SortResult::DoubleEdge, posIndex); OutputDebugString("Double Edge!"); ReleaseImage(proSubRot); continue; } } //Is body/cap short long upEdge = 0, downEdge = 0; bool findEdge = FindUpDownEdge( proSubRot, m_segmentParam.edgeDensity, m_segmentParam.edgeThres, upEdge, downEdge); if (findEdge) { if (false == TransIsPartShort(height, upEdge, downEdge)) { if (REALTIME == mode) { m_sortResult.SetResult(SortResult::PartShort, posIndex); OutputDebugString("Part Short!"); ReleaseImage(proSubRot); continue; } } } //Soble Analysis if( false == TransSobelAnalysis(proSubRot)) { if (REALTIME == mode) { m_sortResult.SetResult(SortResult::SobelErr, posIndex); OutputDebugString("Sobel Edge!"); ReleaseImage(proSubRot); continue; } } //blobAnalysis if(false == TransBlobAnalysis( proSubRot, upEdge, downEdge, m_segmentParam.dynWndSize, m_segmentParam.dynThres, m_segmentParam.blobSize)) { if (REALTIME == mode) { m_sortResult.SetResult(SortResult::BlobErr, posIndex); ReleaseImage(proSubRot); OutputDebugString("BlobErr!"); continue; } } ReleaseImage(proSubRot); } } unsigned int badResult = m_sortResult.GetErrorPosition(); m_sortObserver.ObserverParam(SortObserver::MResult, badResult & 0x0F); m_sortObserver.ObserverParam(SortObserver::MTime, td.msec() ); if (mode == REALTIME) { if( eSecond == m_processIndex ) { CapsuleProc::AddToAllCount( counter ); } } if(profileBlobCount > 0) { RecordingImage(); } return badResult; }