2019年6月6日 星期四

動態加載(explicit linking) DLL的注意事項


─ 問題描述:
一開始測試載dll的時候,一直都載不進程式中,用depends22_86這個軟體檢查dll 檔,確認是否有我定義的函式進入點,檢查結果是有的。

DLL的程式碼如下:
VC14Dll.h
#pragma once
#include "opencv2\opencv.hpp"
#include <windows.h>
#ifdef VC14DLL_EXPORTS
#define VC14DLL_EXPORTS __declspec(dllexport)
#else
#define VC14DLL_EXPORTS __declspec(dllimport)
#endif //  DLLEXPORT
VC14DLL_EXPORTS int Test(cv::Mat input);
VC14DLL_EXPORTS void Test2();

2019年5月29日 星期三

C Sharp BitmapImage、Bitmap、HImage問的互相轉換

這篇筆記是C Sharp 的wpf BitmapImage、windows form Bitmap以及Halcon的HImage、HObject間的轉換。
語法及程式碼很多,但基本上都是都把影像的指標data取出後再轉換。

2019年5月26日 星期日

[log book]ubuntu 下 vs code 黑畫面無法開啟的解決方法

問題描述:
因為一開始vs code不會使用,以為是有什麼少安裝了,所以重裝,重裝完後一打開就是黑畫面。
至此之後,無論怎麼重裝,或是換不同的安裝方式,都是一樣的結果。

[log book]C++ struct指標一直出現「變數尚未初始化」的訊息

─ 狀況說明
下面程式碼一直出現「變數尚未初始化」的錯誤訊息
void main()
{
        InspectionRegion *test;
        test->regionHeight = 10;
        test->startPointsOfEachRow = new hsPoint[10];
        test->endPointsOfEachRow = new hsPoint[10];
        
        for (int i = 0; i < 10; i++)
        {
               (test->startPointsOfEachRow + i)->X = i;
               (test->startPointsOfEachRow + i)->Y = i + 10;
               (test->endPointsOfEachRow + i)->X = i + 20;
               (test->endPointsOfEachRow + i)->Y = i + 30;
        }
}

[log book] 當檔案無法從本機拉進VM的解決方法

─ 問題
灌好新的VM後,無法將檔案拉進新的VM,設定shared folder也有問題

─ 解決方法

[log book] hom_mat2d_translate_local 坐標問題

[問題描述]
今天用hom_mat2d_translate_local (HomMat2DIdentity, shiftPixels[i], 0, HomMat2DTranslate) 來移動x坐標,
但在affine後發現,怎麼動的都只有y坐標,我明明y的偏移量是設0啊!!!

[解題思路]

[log book] 解決VS2008 exe使用VS2015的dll並delete VS2015 dll new出來的變數導致程式崩潰

[問題描述]
延續《 [log book] 解決演算法結果接口介面化的問題 ─ 要改變指標,請用指標的指標(雙重指標)》之後,又遇到了一個問題,由於我的dll是使用VS2015寫的,但機台的子機程式是用VS2008寫的,當我在exe中釋放的時候,就會出問題。
下圖中,要釋放的記憶體空間result是我在exe中宣告出的記憶體空間,作用是接dll中演算法的運算結果的


[解題思路]
讀到zj510大大的博客《跨DLL的内存分配释放问题 Heap corruption》,雖然裡面在探討的議題與我遇到的稍微不一樣,但看到z大所寫到的:「在一个DLL里面分配内存,然后在DLL的调用者EXE那里释放内存。当DLL和EXE里面有一个是使用MT连接CRT的时候就有问题。如果DLL和EXE都使用MD,那么就没有问题。」,我突然想到:「我應該在dll中釋放dll宣告的記憶體」。

[解決方法]
在dll檔的類別及介面(interface)中,多宣告一個方法釋放dll的記憶體空間的方法 ─ releaseResult
介面的宣告如下
#pragma once
#include "HsStruct.h"
typedef void Result;
class HInspectAlgoInterface
{
public:
        virtual ~HInspectAlgoInterface() { ; }
        virtual bool inspect(ImageParam imgParam, wdb_type *wd, hole_type *md) = 0;
        //virtual bool getResult(std::string Type, int *Num, Result **Ret) = 0;
        virtual bool getResult(char* Type, int *Num, Result **Ret) = 0;
        virtual bool releaseResult(Result **Ret) = 0;
};


releaseResult的定義如下
bool IrrBurCheckAlgo::releaseResult(Result **Ret)
{
        try {
               if (*Ret){
                       delete[] * Ret;
                       *Ret = NULL;
               }
               return true;
        }
        catch (std::exception ex) {
               return false;
        }
}



執行結果如下:

結論:dll new出來的記憶體位置最好由dll自己釋放

不過後來我有發現:若使用的VS 版本一樣,且都是用MD,就不會發生這個問題

下面提供測試版的程式碼:

VS 2015 dll的程式碼:(用MD編譯)
HInspectAlgoInterface.h
#pragma once
#include "HsStruct.h"
typedef void Result;
class HInspectAlgoInterface
{
public:
        virtual ~HInspectAlgoInterface() { ; }
        virtual bool inspect(ImageParam imgParam, wdb_type *wd, hole_type *md) = 0;
        virtual bool getResult(char* Type, int *Num, Result **Ret) = 0;
        virtual bool releaseResult(Result **Ret) = 0;
};

HsStruct.h
#ifndef _HSSTRUCT_H_
#define _HSSTRUCT_H_

typedef struct {
        long id;
        long chip;
        long no;
        long Left;
        long Top;
        long width;
        long height;
}wdb_type;

typedef struct{
        long hole_size;
        long hole_x;
        long hole_y;
        long hole_dx;
        long hole_dy;
}hole_type;

typedef struct{
        unsigned char *Src;
        int Width;
        int Height;
} ImageParam;

[Log Book] wpf 使用Halcon dotnet資料型態發生 BadImageFormatException HRESULT: 0x8007000B

[問題描述]
在c sharp wpf中使用Halcon的資料型態HObject 及HImage時,一直發生的錯誤訊息:「
於 System.BadImageFormatException 擲回例外狀況: 'halcondotnet.dll'
於 System.BadImageFormatException 擲回例外狀況: 'halcondotnet.dll'
In ImageTypeConverter.Bitmapimage2Hobject: 試圖載入格式錯誤的程式。 (發生例外狀況於  HRESULT: 0x8007000B)

[Log book] GDB-image watch安裝時出現from giwscripts.thirdparty.pysigset import pysigset無法import pysigset的錯誤

─ 遇到的問題
執行
python3 gdb-imagewatch.py --test
後出現 from giwscripts.thirdparty.pysigset import pysigset無法import pysigset的錯誤

─ 解決思路
「from giwscripts.thirdparty.pysigset import pysigset無法import pysigset」這個語法感覺就是是要從giwscripts下的thirdparty下的pysigset載入pysigset這個package。
所以我到thirdparty這個資料夾下的pysigset中,發現根本沒有任何檔案。
後來我真的去找pysigset,發現它在根目錄下
/usr/local/lib/python3.6/dist-packages/

─ 解決方法

2019.05.23 操作多通道影像的技巧

最近在找MSDN上WriteableBitmap的影像指標操作資料時,看到了一個很有趣的東西 ─ 四通道影像的操作方式
範例中使用一個int一次讀取四個通道,並用使用位元運算子,依相對順序將值移到相對應的位置

ubuntu 18 GDB-image watch 安裝筆記

平時在windows下開發影像處理的演算法時,都使用Visual Studio的外掛 ─ image watch 觀看影像變數的變化、幫忙debug,後來想到linux的環境下玩玩,但用linux寫演算法時,debug就明顯得相當困難。後來,筆者找到了一位國外的工程師開發的linux版的image watch,這位大哥超強,利用GDB觀看記憶體中的變數的能力,搭配python及qt,寫出了一個外掛,並命名為GDB-image watch[1]。
廢話不多說,來看看怎麼安裝吧!