problem z opencv

0
    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:

newMask += tray;
0

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

0

Hej,

mam takie wartości:

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

0
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.

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/proje[...].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:

    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<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]);
    }

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

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

na ostatniej linii

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:

(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.

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ć?

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0