https://lsongbeeimageprocessingblablabla.wordpress.com/
這裡的文章還是會留著,只是不再更新
在影像的應用是以Graph-base來做影像分割(image segmentation), 其特點在於把圖論 G = (V, E)中的 E 建立方式
把常用的

改良為

如同演算名所揭示的Neighborhood期以鄰近的資料來推演與標記資料
資料標記化的處理程序為

參考資料
參考資料中不懂的幾個名詞或縮寫
1. 為方便稍後的設定與未來專案的移植性,在安裝完OpenCV 3.0後首先要設定OpenCV的環境目錄,使用管理員的權限開啟Command視窗輸入
1: setx -m OPENCV_DIR e:\sdk\opencv\build2. 開啟VS2012,匯入我設定好的property setting (OpenCV300.zip),OpenCV300.props的內容如下:
1: <?xml version="1.0" encoding="utf-8"?>
2: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
3: <ImportGroup Label="PropertySheets" />
4: <PropertyGroup Label="UserMacros" />
5: <PropertyGroup>
6: <IncludePath>$(OPENCV_DIR)\include;$(IncludePath)</IncludePath>
7: <LibraryPath Condition="'$(Platform)'=='Win32'">$(OPENCV_DIR)\x86\vc11\staticlib;$(LibraryPath)</LibraryPath>
8: <LibraryPath Condition="'$(Platform)'=='X64'">$(OPENCV_DIR)\x64\vc11\staticlib;$(LibraryPath)</LibraryPath>
9: </PropertyGroup>
10: <ItemDefinitionGroup>
11: <Link Condition="'$(Configuration)'=='Debug'">
12: <AdditionalDependencies>ippicvmt.lib;IlmImfd.lib;libjasperd.lib;libjpegd.lib;libpngd.lib;libtiffd.lib;libwebpd.lib;opencv_calib3d300d.lib;opencv_core300d.lib;opencv_features2d300d.lib;opencv_flann300d.lib;opencv_hal300d.lib;opencv_highgui300d.lib;opencv_imgcodecs300d.lib;opencv_imgproc300d.lib;opencv_ml300d.lib;opencv_objdetect300d.lib;opencv_photo300d.lib;opencv_shape300d.lib;opencv_stitching300d.lib;opencv_superres300d.lib;opencv_ts300d.lib;opencv_video300d.lib;opencv_videoio300d.lib;opencv_videostab300d.lib;zlibd.lib;%(AdditionalDependencies)</AdditionalDependencies>
13: </Link>
14: <Link Condition="'$(Configuration)'=='Release'">
15: <AdditionalDependencies>ippicvmt.lib;IlmImf.lib;libjasper.lib;libjpeg.lib;libpng.lib;libtiff.lib;libwebp.lib;opencv_calib3d300.lib;opencv_core300.lib;opencv_features2d300.lib;opencv_flann300.lib;opencv_hal300.lib;opencv_highgui300.lib;opencv_imgcodecs300.lib;opencv_imgproc300.lib;opencv_ml300.lib;opencv_objdetect300.lib;opencv_photo300.lib;opencv_shape300.lib;opencv_stitching300.lib;opencv_superres300.lib;opencv_ts300.lib;opencv_video300.lib;opencv_videoio300.lib;opencv_videostab300.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
16: </Link>
17: </ItemDefinitionGroup>
18: <ItemGroup />
19: </Project>
若編譯的環境為VS2013則將上述的設定檔中的vc11改為vc12即可。
由於使用的是static lib所以原專案的runtime library也必需改為/MT或/MTd
若想要讓產生的Task具有可取消的機制,則必需透過以下static methods取得task handle與傳入cancel token來達成
Task.Run(Action, CancellationToken)
Task.Run(Func<Task>, CancellationToken)
Task.Run<TResult>(Func<Task<TResult>>, CancellationToken)
Task.Run<TResult>(Func<TResult>, CancellationToken)
這個範例是我設計的一個對話盒控制項,當對話盒產生時呼叫InitItemsAsync以非同步的方式產生圖片對載入UI的list控制項中,使用者可以不必等待所有的圖片都產生即按下OK(或Cancel)按來關閉這個對話盒。因此我必需讓InitItemsAsync具有可被取消的機制。
1: public sealed partial class MyDialog : UserControl
2: {3: private CancellationTokenSource _cts;
4: private CancellationToken _token;
5: private Task _opInit;
#3-5 我們的物件必需儲存CancellationTokenSource、CancellationToken與Task方便在動作的對應函式中取消
1: private async Task InitItemsAsync()
2: {3: for(int i=0 ; i<24 ; i++)
4: {5: if (_token.IsCancellationRequested) break;
6: 7: await LoadImageAsync(i); 8: } 9: }#5 非同步的InitItemsAsync函式,當_token收到取消的要求時(IsCancellationRequested)提前結束迴圈
1: _cts = new CancellationTokenSource();
2: _token = _cts.Token; 3: _opInit = Task.Run(async () => 4: { 5: await InitItemsAsync(); 6: }, 7: _token);透過Task.Run來執行非同步的函式,並載入cancel token。
#5 InitItemAsync是非同步的函式,因此必需有async / await來載明
PS: 我嘗試過不用Lambda的寫法,而是直接以函式指標的方式來使用Task.Run,但在VS2013編譯時期會有函式型別模糊(error CS0121: The call is ambiguous between the following methods or properties)的錯誤,目前還不知道解決的方式。
1: private bool TryCancelInitItems()
2: {3: if (_opInit.IsCompleted == false)
4: {5: try
6: { 7: _cts.Cancel(); 8: 9: _opInit.Wait(_token); 10: 11: return true;
12: }13: catch(System.OperationCanceledException)
14: {15: return true;
16: }17: catch (Exception e)
18: {19: Debug.WriteLine(@"{0}", e);
20: 21: return false;
22: } 23: } 24: 25: return true;
26: }#3 先檢查task是否已經完成,若尚未完成才需使用取消機制
#7 呼叫取消並等待_token
#13 若InitItemsAsync被取消了,會丟出System.OperationCanceledException
Windows 8.1的一個德政是取消了原本的Snappped View限制,App除了FullScreen外還可以有任意的大小(只是有最小限制)。不過對於已經開發好的8.0 App,就要花時間重新調整不同視窗大小時Layout。
我的懶人改法是,除了FullScreen外一律視為Snapped。依這樣的邏輯其實只要改動一個function – LayoutAwarePage的DetermineVisualState:
1: protected virtual string DetermineVisualState(ApplicationView appView)
2: {3: if(appView.IsFullScreen)
4: {5: return @"FullScreen" + appView.Orientation.ToString();
6: }7: else
8: {9: return @"Snapped";
10: } 11: }1. 原本參數為ApplicationViewState (編譯時有warning),改為ApplicationView
3-10. 原本view state可以直接吐回字串的部份用邏輯修正
當然呼叫端也要調整為
1: string visualState = DetermineVisualState(ApplicationView.GetForCurrentView());
升上8.1第一天後, 我的App發生DirectWrite繪製文字有時會繪製不出來的問題。最後才發現改IDWriteFactory改為IDWriteFactory2後就一切正常,不過IDWriteFactory2只支援8.1以上,所以結論是App必做二個版本了。。。
最近在學習W8App的Direct2D與DirectWrite時發生了一個例外的錯誤,當呼叫D2D的EndDraw來更新繪圖結果是產生了0x88990012 (D2DERR_WRONG_FACTORY)的例外錯誤。
這個錯誤發生的原因是我的DirectWrite Render物件預先儲存了D2D factory,而透過SurfaceImageSource來連結W8App與Direct2D時,D2DContext所使用的D2D factory似乎有自已獨立的產生方式。
目前的解決方式是透過GetFactory直接從D2DContext物件中取得D2DFactory,至於是否有更好的作法,就需要再研究。
1: IFACEMETHODIMP CustomTextRenderer::DrawGlyphRun(2: _In_opt_ void* clientDrawingContext,
3: FLOAT baselineOriginX, 4: FLOAT baselineOriginY, 5: DWRITE_MEASURING_MODE measuringMode,6: _In_ DWRITE_GLYPH_RUN const* glyphRun,
7: _In_ DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
8: IUnknown* clientDrawingEffect 9: ) 10: { 11: HRESULT hr = S_OK; 12: 13: Microsoft::WRL::ComPtr<ID2D1Factory> d2dFactory; 14: m_d2dContext->GetFactory(&d2dFactory); 15: 16: // Create the path geometry.
17: Microsoft::WRL::ComPtr<ID2D1PathGeometry> pathGeometry; 18: hr = d2dFactory->CreatePathGeometry(&pathGeometry); 19: 20: // Write to the path geometry using the geometry sink.
21: 22: Microsoft::WRL::ComPtr<ID2D1GeometrySink> sink;23: if (SUCCEEDED(hr))
24: { 25: hr = pathGeometry->Open(&sink); 26: } 27: 28: // Get the glyph run outline geometries back from DirectWrite and place them within the
29: // geometry sink.
30: if (SUCCEEDED(hr))
31: { 32: hr = glyphRun->fontFace->GetGlyphRunOutline( 33: glyphRun->fontEmSize, 34: glyphRun->glyphIndices, 35: glyphRun->glyphAdvances, 36: glyphRun->glyphOffsets, 37: glyphRun->glyphCount, 38: glyphRun->isSideways, 39: glyphRun->bidiLevel %2, 40: sink.Get() 41: ); 42: } 43: 44: // Close the geometry sink
45: if (SUCCEEDED(hr))
46: { 47: hr = sink.Get()->Close(); 48: } 49: 50: // Initialize a matrix to translate the origin of the glyph run.
51: D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F(
52: 1.0f, 0.0f, 53: 0.0f, 1.0f, 54: baselineOriginX, baselineOriginY 55: ); 56: 57: // Create the transformed geometry
58: Microsoft::WRL::ComPtr<ID2D1TransformedGeometry> transformedGeometry;59: if (SUCCEEDED(hr))
60: { 61: hr = d2dFactory->CreateTransformedGeometry( 62: pathGeometry.Get(), 63: &matrix, 64: &transformedGeometry 65: ); 66: } 67: 68: // Draw the outline of the glyph run
69: if(SUCCEEDED(hr))
70: { 71: m_d2dContext->DrawGeometry(transformedGeometry.Get(),m_brushOutline.Get()); 72: m_d2dContext->FillGeometry(transformedGeometry.Get(),m_brushFill.Get()); 73: } 74: 75: return hr;
76: }13-14 透過目前的D2DContext來取得D2DFactory
隱藏滑鼠指標
1: if (Window.Current.CoreWindow.PointerCursor != null) Window.Current.CoreWindow.PointerCursor = null;
顯示滑鼠指標
1: if (Window.Current.CoreWindow.PointerCursor == null)
2: {3: Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 1);
4: }CoreCursor的id可以自已隨意的指派並不一定是1。
Reference: