Color shadeWithMaterial(struct Scene* scene, struct HitRecord* record, Ray ray, int depth) { Color result = {0,0,0}; Material material = *record->triangle->material; struct HitRecord temp_record = createHitRecord(); Vector position = record->point; Vector new_direction; if(depth == scene->max_depth) { return result; } if(material.is_light) { return material.color; } Vector normal = record->triangle->normal; float costheta = dotVector(normal, ray.direction); if(costheta > 0) { normal = negateVector(normal); } float path = (double)rand()/(double)RAND_MAX; // diffuse BRDF if(path < .33) { new_direction = getDiffuseDirection(normal); } // BRDF (which is also diffuse) else if(path < .66) { new_direction = getDiffuseDirection(normal); } // point to light else { new_direction = getLightDirection(scene, position); } Ray new_ray = {position, new_direction}; resetHitRecord(&temp_record); float cosphi = dotVector(normal, new_direction); if(cosphi > 0) { result = addColors(result, multiplyColorByNumber(hitScene(scene, &temp_record, new_ray, depth + 1), cosphi)); } return multiplyColors(result, material.color); }
features_t getFeatures(vector<int> leftEyeDistances, vector<int> rightEyeDistances) { vector<int> distances; int i; features_t features; for (i = 0; i < leftEyeDistances.size(); i++) { distances.push_back((int)round((leftEyeDistances[i] + rightEyeDistances[i]) / 2.0)); } int minVal, maxVal; int minInd, maxInd; vectorGetMax(distances, &maxVal, &maxInd); vectorGetMin(distances, &minVal, &minInd); double threshold = 0.9 * (minVal + maxVal) / 2.0; vector<int> eyeClosed = ourFind(vectorTo01(distances, threshold)); /* Percentage of eyelid closure */ features.PERCLOS = eyeClosed.size() / (double)distances.size(); /* Maximum closed duration */ features.MCD = 0; int summary = 1; for (i = 1; i < eyeClosed.size(); i++) { if (eyeClosed[i] == eyeClosed[i - 1] + 1) { summary++; } else { if (features.MCD < summary) { features.MCD = summary; } summary = 1; } if (i == eyeClosed.size() - 1) { if (features.MCD < summary) { features.MCD = summary; } summary = 1; } } features.MCD *= SAMPLING_PERIOD; /* Blinking frequency */ vector<int> negatedDistances = negateVector(distances); vector<int> locs; vector<int> peaks; findPeaks(&negatedDistances, &locs, &peaks, -(int)round(threshold)); features.BF = 60 * peaks.size() / ((double)distances.size() * SAMPLING_PERIOD); /* Opening velocity and closing velocity */ int cntClosing = 0; int cntOpening = 0; vector<int> diffPos = diff(&distances); vector<int> diffNeg = negateVector(diffPos); vector<int> locsPos; vector<int> locsNeg; vector<int> peaksPos; vector<int> peaksNeg; findPeaks(&diffPos, &locsPos, &peaksPos); findPeaks(&diffNeg, &locsNeg, &peaksNeg); vector<int> locsAll = locsPos; locsAll.insert(locsAll.end(), locsNeg.begin(), locsNeg.end()); locsAll.insert(locsAll.end(), locs.begin(), locs.end()); sort(locsAll.begin(), locsAll.end()); int opened; int state; features.OV = 0; features.CV = 0; vector<int> locsBlink = locs; if (locsAll.empty()) { cout << "Jebo te bog" << endl; } else { for (i = 0; i < locsAll.size() - 1; i++) { if ((find(locsPos.begin(), locsPos.end(), locsAll[i]) != locsPos.end()) || (find(locsNeg.begin(), locsNeg.end(), locsAll[i]) != locsNeg.end())) { opened = 1; } else { opened = 0; } if ((find(locsPos.begin(), locsPos.end(), locsAll[i + 1]) != locsPos.end()) || (find(locsNeg.begin(), locsNeg.end(), locsAll[i + 1]) != locsNeg.end())) { if (opened) { state = 0; } else { state = 1; } } else { if (opened) { state = -1; } else { state = 0; } } if(state == -1) { features.CV += abs(distances[locsAll[i]] - distances[locsAll[i+1]]) / abs(locsAll[i] - locsAll[i + 1]); /* pixels/frame */ cntClosing++; } else if (state == 1) { features.OV += abs(distances[locsAll[i]] - distances[locsAll[i + 1]]) / abs(locsAll[i] - locsAll[i + 1]); /* pixels/frame */ cntOpening++; } } features.CV /= cntClosing; features.OV /= cntOpening; } vector<int> eyeOpened = ourFind(invert01(vectorTo01(distances, threshold))); int AOLSum = 0; for (i = 0; i < eyeOpened.size(); i++) { AOLSum += distances[i]; } features.AOL = ((double)AOLSum / (double)eyeOpened.size()) / maxVal; return features; }
int eyelidDistance(Mat eye, double threshold) { int i; int j; int m = eye.rows; int n = eye.cols; Mat strechedEye = stretchHistogram(&eye); vector<int> summary = sum(&strechedEye, 2); vector<int> eyebrowPeaks; vector<int> eyebrowLocs; findPeaks(&summary, &eyebrowLocs, &eyebrowPeaks); Mat eyeBinary = binarize(&strechedEye, 55); if (!eyebrowLocs.empty()) { if (eyebrowLocs[0] != 1 && eyebrowLocs[0] < round(m / 2.2)) { eyeBinary.rowRange(0, eyebrowLocs[0] - 1) = 1; } } vector<double> mBinary = meanValue(&eyeBinary, 2); vector<double> sigmaBinary(m); for (i = 0; i < m; i++) { double tmpSum = 0; for (j = 0; j < n; j++) { tmpSum += (eyeBinary.at<uchar>(i, j) - mBinary[i])*(eyeBinary.at<uchar>(i, j) - mBinary[i]); } sigmaBinary[i] = tmpSum / n; } vector<double> difVarBinary = diff(&sigmaBinary); vector<double> pksBinaryPositive; vector<int> locsBinaryPositive; vector<double> pksBinaryNegative; vector<int> locsBinaryNegative; findPeaks(&difVarBinary, &locsBinaryPositive, &pksBinaryPositive); findPeaks(&(negateVector(difVarBinary)), &locsBinaryNegative, &pksBinaryNegative); vector<double> pksBinary = pksBinaryPositive; vector<double> negatedPeaks = negateVector(pksBinaryNegative); pksBinary.insert(pksBinary.end(), negatedPeaks.begin(), negatedPeaks.end()); vector<int> locsBinary = locsBinaryPositive; locsBinary.insert(locsBinary.end(), locsBinaryNegative.begin(), locsBinaryNegative.end()); int loc1, loc2; getDistance(pksBinary, locsBinary, &loc1, &loc2); int distance = abs(loc2 - loc1); double percent = 0; if (distance < threshold) { return 0; } else { if (loc1 != 0 || loc2 != 0) { if (loc1 < loc2) { Mat extract = eyeBinary.rowRange(loc1, loc2); vector<int> sumH = sum(&invert(&extract), 2); int boundariesH1; int boundariesH2; int boundariesV1; int boundariesV2; getBigInterval(sumH, &boundariesH1, &boundariesH2, 0.85); vector<int> sumV = sum(&invert(&extract), 1); getBigInterval(sumV, &boundariesV1, &boundariesV2, 0.65); Mat cut = extract(Range(boundariesH1, boundariesH2), Range(boundariesV1, boundariesV2)); percent = 100 * (sum(cut))[0] / (double)(cut.rows * cut.cols); } } if (percent > 25) { return 0; } else { return distance; } } }