problem z opencv

Tomasz Olszewski
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6
0
Kopiuj
	Mat newMask = Mat::zeros(mask.size(), mask.type());
	for (int i=0; i< 3; i++){
		Mat tray = Mat::zeros(mask.size(), mask.type());
		inRange(mask,i+1, i+1, tray);
		cv::erode(tray, tray, getStructuringElement(MORPH_RECT, Size(5, 5)), Point(-1, -1));
		newMask += tray;
	}

czy ta metoda powinna w ogóle dzialac? dostałem ja od klienta ale zwraca mi:

Sizes of input arguments do not match) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function 'arithm_op'

przy linii:

Kopiuj
newMask += tray;
GS
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1265
0

U mnie działa.
Jaką masz wartość mask.type() i mask.size()?

Tomasz Olszewski
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6
0

Hej,

mam takie wartości:

mask size = [257 x 257]
mask type = 16

GS
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1265
0
Kopiuj
cv::Mat mask(cv::Size(257,257), 16);

cv::Mat newMask = cv::Mat::zeros(mask.size(), mask.type());
for(int i=0; i< 3; i++) {
    cv::Mat tray = cv::Mat::zeros(mask.size(),mask.type());
    cv::inRange(mask, i+1, i+1, tray);
    cv::erode(tray,tray,cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5,5)), cv::Point(-1,-1));
    newMask += tray;
}

powyższy kod kompiluje się bez problemu w OpenCV 3.4, gcc 5.4.0.
Zastosuj najpierw jawnie wszedzie namespace cv:: przed nazwami. Sprobuj tez zrobic czysty projekt i sprobowac zbudowac tylko ten fragment. Mozesz tez zakomentowac linię ktora powoduje blad, tak zeby sie zbudowalo i w debugerze sprawdzic wymiary newMask i tray w momencie gdy mialaby sie wykonac.

Wklej też cały wypis kompilatora, który informuje o błędzie, zeby miec jakis kontekst.

Tomasz Olszewski
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6
0

używam OpenCV w wersji 4.1.2 a więc najnowszej

kod konwertuje na Obj-C i używam w aplikacji iOS

EDIT: sciągnąłem wersje CV_VERSION = 3.4.8

https://sourceforge.net/projects/opencvlibrary/files/3.4.8/opencv-3.4.8-ios-framework.zip/download

wpiąłem w aplikację i crash jest ten sam:

wypis kompilatora:

libc++abi.dylib: terminating with uncaught exception of type cv::Exception: OpenCV(3.4.8) /Volumes/build-storage/build/3_4_iOS-mac/opencv/modules/core/src/arithm.cpp:663: error: (-209:Sizes of input arguments do not match) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function 'arithm_op'

EDIT2:

użyłem kodu:

Kopiuj
    cv::Mat newMask = cv::Mat::zeros(mask.size(), mask.type());
    for(int i=0; i< 3; i++) {
        cv::Mat tray = cv::Mat::zeros(mask.size(),mask.type());
        cv::inRange(mask, i+1, i+1, tray);
        cv::erode(tray,tray,cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5,5)), cv::Point(-1,-1));
        newMask += tray;
    }

i nadal to samo

na slackoverlow dostałem informacje aby dodać:

cvtColor(newMask,newMask,CV_BGR2GRAY);

przed pętlą for ale wtedy wywala się w innym miejscu

cały kod po zmianach metody wygląda tak:

  • (Vec3f)getFeats:(Mat&)mask {
    cout << "CV_VERSION = " << CV_VERSION << endl;

    cv::Mat newMask = cv::Mat::zeros(mask.size(), mask.type());
    for(int i=0; i< 3; i++) {
    cv::Mat tray = cv::Mat::zeros(mask.size(),mask.type());
    cv::inRange(mask, i+1, i+1, tray);
    cv::erode(tray,tray,cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5,5)), cv::Point(-1,-1));
    newMask += tray;
    }

    vector<vectorcv::Point > contours;
    findContours( newMask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE );

    vector<float> v;
    for( int i = 0; i< contours.size(); i++ ){
    v.push_back(cv::contourArea(contours[i])/(mask.size[0]*mask.size[1]));
    }
    sort(v.begin(), v.end(), std::greater<float>());
    return Vec3f(v[0], v[1], v[2]);
    }

contours.size(); jest puste więc v tez jest puste i wywala

Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

na ostatniej linii

GS
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1265
0
Tomasz Olszewski napisał(a):

na slackoverlow dostałem informacje aby dodać:

cvtColor(newMask,newMask,CV_BGR2GRAY);

przed pętlą for ale wtedy wywala się w innym miejscu

cały kod po zmianach metody wygląda tak:

Kopiuj
(Vec3f)getFeats:(Mat&)mask {
    cout << "CV_VERSION = " << CV_VERSION << endl;
    
    cv::Mat newMask = cv::Mat::zeros(mask.size(), mask.type());
    for(int i=0; i< 3; i++) {
        cv::Mat tray = cv::Mat::zeros(mask.size(),mask.type());
        cv::inRange(mask, i+1, i+1, tray);
        cv::erode(tray,tray,cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5,5)), cv::Point(-1,-1));
        newMask += tray;
    }

    vector<vector<cv::Point> > contours;
    findContours( newMask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE );

    vector<float> v;
    for( int i = 0; i< contours.size(); i++ ){
        v.push_back(cv::contourArea(contours[i])/(mask.size[0]*mask.size[1]));
    }
    sort(v.begin(), v.end(), std::greater<float>());
    return Vec3f(v[0], v[1], v[2]);
}

Nie widzę, żebyś powyżej dokonał tej zmiany cvtColor(newMask,newMask,CV_BGR2GRAY). Nie wiem też czemu miałaby być potrzebna przed pętlą. W końcu przeszło Ci bez niej czy z nią?
findContours działa dla 8-bitowych obrazów jednokanałowych. Typ 16 który podałeś wcześniej, jeśli dobrze pamiętam, odpowiada CV_8UC3, czyli 3 kanałowemu obrazowi. Wydaje mi się, że przekształcenia BGR2GRAY powinieneś dokonać po wyznaczeniu maski a przed szukaniem konturów. Warto też sprawdzić czy newMask po swojej pętli nie jest puste - podejrzyj to sobie w debugerze albo zapisując na dysk w postaci YAMLa.

Tomasz Olszewski
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6
0

Dzięki za szybką odpowiedź.

Nie widzę, żebyś powyżej dokonał tej zmiany cvtColor(newMask,newMask,CV_BGR2GRAY). Nie wiem też czemu miałaby być potrzebna. W końcu przeszło Ci bez niej czy z nią?

contours.size(); jest puste więc v tez jest puste i wywala

Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

fakt, tego w kodzie nie ma ale jak pisałem po dodaniu cvtColor(newMask,newMask,CV_BGR2GRAY) mam EXC_BAD_ACCESS (code=1, address=0x0) zapewne dlatego ze contours.size(); jest puste

Pytanie z innej beczkim rozmawiam z gościem od CV i proponuje wcześniej segmentationMap które mam jako Int na: "cv2 matrix with type cv_8U cpp"

czy wiecie jak to zrobić?

GS
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1265
0
Tomasz Olszewski napisał(a):

Pytanie z innej beczkim rozmawiam z gościem od CV i proponuje wcześniej segmentationMap które mam jako Int na: "cv2 matrix with type cv_8U cpp"

czy wiecie jak to zrobić?

Chyba nie rozumiem pytania. Typ CV_8U to jest typ całkowity, konkretnie 8-bitowy, unsigned int, znany również jako char.
Wracając do właściwego problemu: zakomentuj feralną linijkę tak żeby wszystko się budowało i wyświetl sobie w jej miejscu wartości newMask.type(), newMask.size(), tray.type(), tray.size(). Możliwe, że przy konwersji na iOS dochodzi do jakichś niejawnych podmian typów.
W ogóle radzę przyjąć taką strategię rozwiązywania problemów: dąż do wyizolowania minimalnego problemu. Jeśli widzisz, że jakaś konkretna linijka się nie kompiluje, sprawdzaj wszystkie konieczne warunki do przejścia, przede wszystkim typy argumentów wejściowych i wyjściowych. Jeśli się kompiluje, ale jej efekt nie jest taki jak się spodziewasz, sprawdzaj dokładnie wartość argumentów wejściowych.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.