// /// Maps the points of the printer DC to the screen DC. Sets the screen window /// extent equal to the maximum logical pointer of the printer DC. /// /// It is assumed that the viewport extents of the screen DC /// are already set and represent the full previewed page. /// The window extents are set to the page size in logical units /// as defined by the printer DC. // void TPrintPreviewDC::ReScale() { // Get the extents of the screen viewport in device units (pixels). // This should represent the whole previewed page on the screen. TSize ve; ::GetViewportExtEx(GetHDC(), &ve); // Calculate the size of the previewed page in logical units. TSize page = GetPageSizeInPixels(PrnDC); TSize pve = PrnDC.GetViewportExt(); TSize pwe = PrnDC.GetWindowExt(); TSize we(MulDiv(page.cx, pwe.cx, pve.cx), MulDiv(page.cy, pwe.cy, pve.cy)); // Set the mapping mode and scale. ::SetMapMode(GetHDC(), MM_ANISOTROPIC); ::SetWindowExtEx(GetHDC(), we.cx, we.cy, 0); ::SetViewportExtEx(GetHDC(), ve.cx, ve.cy, 0); // Set the origin for logical units. ReOrg(); }
static void mouseWheel(QWindow* window, QObject* item, Qt::MouseButtons buttons, Qt::KeyboardModifiers stateKey, QPointF _pos, int xDelta, int yDelta, int delay = -1) { QTEST_ASSERT(window); QTEST_ASSERT(item); if (delay == -1 || delay < QTest::defaultMouseDelay()) delay = QTest::defaultMouseDelay(); if (delay > 0) QTest::qWait(delay); QPoint pos; QQuickItem *sgitem = qobject_cast<QQuickItem *>(item); if (sgitem) pos = sgitem->mapToScene(_pos).toPoint(); QTEST_ASSERT(buttons == Qt::NoButton || buttons & Qt::MouseButtonMask); QTEST_ASSERT(stateKey == 0 || stateKey & Qt::KeyboardModifierMask); stateKey &= static_cast<unsigned int>(Qt::KeyboardModifierMask); QWheelEvent we(pos, window->mapToGlobal(pos), QPoint(0, 0), QPoint(xDelta, yDelta), 0, Qt::Vertical, buttons, stateKey); QSpontaneKeyEvent::setSpontaneous(&we); // hmmmm if (!qApp->notify(window, &we)) QTest::qWarn("Wheel event not accepted by receiving window"); }
int CWindowIterator::Callback_Iterator(HWND hWnd) { if (m_hWnd && GetParent(hWnd) != m_hWnd) return 0; CWindowEntry &we(mWindows.GetAt(mWindows.Add(hWnd))); we.UpdateDesc(mProcessName); return mCalllback ? mCalllback(we) : 0; }
void testEncodeQP_RFC2047() { // When Quoted-Printable is used, it should be RFC-2047 QP encoding vmime::wordEncoder we( "buffer\xc3\xa0 foo_bar", vmime::charset("utf-8"), vmime::wordEncoder::ENCODING_AUTO); VASSERT_EQ("1", "buffer=C3=A0_foo=5Fbar", we.getNextChunk(100)); }
void testGetNextChunk_integral() { // An integral number of characters should be encoded vmime::wordEncoder we( "buffer\xc3\xa0plop", vmime::charset("utf-8"), vmime::wordEncoder::ENCODING_AUTO); VASSERT_EQ("1", "buffer=C3=A0", we.getNextChunk(7)); VASSERT_EQ("2", "plop", we.getNextChunk(10)); }
/************************************************************************* Change the currently open MenuItem PopupMenu *************************************************************************/ void MenuBase::changePopupMenuItem(MenuItem* item) { if (!d_allowMultiplePopups&&d_popupItem==item) return; if (!d_allowMultiplePopups&&d_popupItem!=0) { d_popupItem->closePopupMenu(false); WindowEventArgs we(d_popupItem->getPopupMenu()); d_popupItem = 0; onPopupClosed(we); } if (item) { d_popupItem = item; d_popupItem->openPopupMenu(false); WindowEventArgs we(d_popupItem->getPopupMenu()); onPopupOpened(we); } }
void QQuickMouseArea::wheelEvent(QWheelEvent *event) { Q_D(QQuickMouseArea); if (!d->enabled || (!isScrollGestureEnabled() && event->source() != Qt::MouseEventNotSynthesized)) { QQuickItem::wheelEvent(event); return; } QQuickWheelEvent we(event->posF().x(), event->posF().y(), event->angleDelta(), event->pixelDelta(), event->buttons(), event->modifiers()); we.setAccepted(d->isWheelConnected()); emit wheel(&we); if (!we.isAccepted()) QQuickItem::wheelEvent(event); }
VMIME_TEST_LIST_END void testGetNextChunk() { // An integral number of characters should be encoded vmime::wordEncoder we( "bufferfoobarbaz", vmime::charset("utf-8"), vmime::wordEncoder::ENCODING_AUTO); VASSERT_EQ("1", "buffer", we.getNextChunk(6)); VASSERT_EQ("2", "foo", we.getNextChunk(3)); VASSERT_EQ("3", "barbaz", we.getNextChunk(10)); }
void QQuickMouseArea::wheelEvent(QWheelEvent *event) { Q_D(QQuickMouseArea); if (!d->enabled) { QQuickItem::wheelEvent(event); return; } QQuickWheelEvent we(event->posF().x(), event->posF().y(), event->angleDelta(), event->pixelDelta(), event->buttons(), event->modifiers()); we.setAccepted(d->isWheelConnected()); emit wheel(&we); if (!we.isAccepted()) QQuickItem::wheelEvent(event); }
void MouseController::handleWheel(WheelEvent & e) {//滚动是忽略capture View * target = e.target(); if (target == root_) target = getTargetByPos(e.getLoc(), true); if (!target) return; WheelEvent we(e.type(), target, e.dx(), e.dy(), target->mapToLocal(e.getLoc()), e.getLoc(), e.getFlags()); EventDispatcher::Push(we); //暂时先这么处理 因为滚动的时候可能离开控件所以 需要改变鼠标样式之类 MouseEvent me(kET_MOUSE_MOVE, kMB_NONE, root_, root_->mapToLocal(last_mouse_point_), last_mouse_point_, 0); handleEvent(me); //if (!capture_) //{//如果没有capture 可能滚动到新的view里 需要shiftOver // shiftIfNecessary(); //} }
/************************************************************************* Handler for mouse button release events *************************************************************************/ void MenuItem::onMouseButtonUp(MouseEventArgs& e) { // default processing ItemEntry::onMouseButtonUp(e); if (e.button == LeftButton) { releaseInput(); // was the button released over this window? // (use mouse position, as e.position in args has been unprojected) if (!d_popupWasClosed && getGUIContext().getRootWindow()->getTargetChildAtPosition( getGUIContext().getMouseCursor().getPosition()) == this) { WindowEventArgs we(this); onClicked(we); } // event was handled by us. ++e.handled; } }
// this is the real one void AtmosphericDrag::doCompute(UTCTime utc, EarthBody& rb, Spacecraft& sc) { // To consist with STK double omega_e = 7.292115E-05; // IERS 1996 conventions //double omega_e = rb.getSpinRate(utc); Vector<double> r = sc.R(); // satellite position in m Vector<double> v = sc.V(); // satellite velocity in m/s const double cd = sc.getDragCoeff(); const double area = sc.getDragArea(); const double mass = sc.getDryMass(); double rmag = norm(r); double beta = cd * area / mass; // [m^2/kg] // compute the atmospheric density double rho = computeDensity(utc, rb, r, v); // [kg/m^3] // debuging... //rho = 6.3097802844338E-12; // compute the relative velocity vector and magnitude Vector<double> we(3,0.0); we(2)= omega_e; Vector<double> wxr = cross(we,r); Vector<double> vr = v - wxr; double vrmag = norm(vr); // form -1/2 (Cd*A/m) rho double coeff = -0.5 * beta * rho; double coeff2 = coeff * vrmag; // compute the acceleration in ECI frame (km/s^2) a = vr * coeff2; ///////// a // Partial reference: Montenbruck,P248 // form partial of drag wrt v // da_dv = -0.5*Cd*(A/M)*p*(vr*transpose(vr)/vr+vr1) Matrix<double> tr(3,1,0.0); tr(0,0)=vr(0); tr(1,0)=vr(1); tr(2,0)=vr(2); Matrix<double> vrvrt = tr*transpose(tr); vrvrt = vrvrt / vrmag; double eye3[3*3] = {1,0,0,0,1,0,0,0,1}; Matrix<double> vrm(3,3,0.0); vrm = eye3; vrm = vrm * vrmag; da_dv = (vrvrt + vrm) * coeff; //////// da_dv // da_dr // da_dr = -0.5*Cd*(A/M)*vr*dp_dr-da_dv*X(w) da_dr.resize(3,3,0.0); Matrix<double> X(3,3,0.0); X(0,1) = -we(2); // -wz X(0,2) = +we(1); // wy X(1,0) = +we(2); // +wz X(1,2) = -we(0); // -wx X(2,0) = -we(1); // -wy X(2,1) = +we(0); // +wx Matrix<double> part1(3,3,0.0); Matrix<double> part2(3,3,0.0); // Get the J2000 to TOD transformation Matrix<double> N = ReferenceFrames::J2kToTODMatrix(utc); // Transform r from J2000 to TOD Vector<double> r_tod = N * r; Position geoidPos(r_tod(0),r_tod(1),r_tod(3)); // Satellite height double height = geoidPos.getAltitude()/1000.0; // convert to [km] const int n = CIRA_SIZE; ; int bracket = 0; if (height >= h0[n-1]) { bracket = n - 1; } else { for (int i = 0; i < (n-1); i++) { if ((height >= h0[i]) && (height < h0[i+1])) { bracket = i; } } } // End 'if (height >= h0[n-1]) ' double Hh = H[bracket]; double coeff4 = -1.0 / (Hh * rmag); Vector<double> drhodr = r*coeff4; Matrix<double> tr2(3,1,0.0); tr2(0,0) = drhodr(0); tr2(1,0) = drhodr(1); tr2(2,0) = drhodr(2); part1 = tr*transpose(tr2); // //Matrix part1 = vr.outerProduct(drhodr); part1 = part1*coeff2; //part1 = dp_dr*a/rho; part2 =-da_dv*X; da_dr = part1-part2; // form partial of drag wrt cd double coeff3 = coeff2 / cd; this->dadcd = vr*coeff3; //////// da_dcd this->da_dcd(0,0) = dadcd(0); this->da_dcd(1,0) = dadcd(1); this->da_dcd(2,0) = dadcd(2); } // End of method 'AtmosphericDrag::doCompute()'
//---------------------------------------------------------------------------- void mitk::vtkEventProvider::ProcessEvents(vtkObject* object, unsigned long event, void* clientData, void* vtkNotUsed(callData)) { vtkEventProvider* self = reinterpret_cast<vtkEventProvider *>( clientData ); vtkRenderWindowInteractor* rwi = static_cast<vtkInteractorStyle *>( object )->GetInteractor(); // base renderer mitk::BaseRenderer* baseRenderer = mitk::BaseRenderer::GetInstance(self->GetRenderWindow()->GetVtkRenderWindow()); switch(event) { // key press case vtkCommand::KeyPressEvent: { VTKEVENTPROVIDER_DEBUG << "key press event"; mitk::KeyEvent mke(mitk::VtkEventAdapter::AdaptKeyEvent(baseRenderer,event,rwi)); self->GetRenderWindow()->keyPressMitkEvent(&mke); break; } // mouse events case vtkCommand::MouseMoveEvent: { VTKEVENTPROVIDER_DEBUG << "mouse move event"; mitk::MouseEvent me(mitk::VtkEventAdapter::AdaptMouseEvent(baseRenderer,event,rwi)); self->GetRenderWindow()->mouseMoveMitkEvent(&me); break; } case vtkCommand::LeftButtonPressEvent: case vtkCommand::MiddleButtonPressEvent: case vtkCommand::RightButtonPressEvent: { VTKEVENTPROVIDER_DEBUG << "mouse press event"; mitk::MouseEvent me(mitk::VtkEventAdapter::AdaptMouseEvent(baseRenderer,event,rwi)); self->GetRenderWindow()->mousePressMitkEvent(&me); break; } case vtkCommand::LeftButtonReleaseEvent: case vtkCommand::MiddleButtonReleaseEvent: case vtkCommand::RightButtonReleaseEvent: { VTKEVENTPROVIDER_DEBUG << "mouse release event"; mitk::MouseEvent me(mitk::VtkEventAdapter::AdaptMouseEvent(baseRenderer,event,rwi)); self->GetRenderWindow()->mouseReleaseMitkEvent(&me); break; } // mouse WHEEL case vtkCommand::MouseWheelForwardEvent: case vtkCommand::MouseWheelBackwardEvent: { VTKEVENTPROVIDER_DEBUG << "mouse wheel event"; mitk::WheelEvent we(mitk::VtkEventAdapter::AdaptWheelEvent(baseRenderer,event,rwi)); self->GetRenderWindow()->wheelMitkEvent(&we); break; } default: VTKEVENTPROVIDER_INFO << "VTK event not mapped properly."; break; } }
void PianoView::wheelEvent(QWheelEvent* event) { int step = event->delta() / 120; double xmag = transform().m11(); double ymag = transform().m22(); if (event->modifiers() == Qt::ControlModifier) { if (step > 0) { for (int i = 0; i < step; ++i) { if (xmag > 10.0) break; scale(1.1, 1.0); xmag *= 1.1; } } else { for (int i = 0; i < -step; ++i) { if (xmag < 0.001) break; scale(.9, 1.0); xmag *= .9; } } emit magChanged(xmag, ymag); int tpix = (480 * 4) * xmag; magStep = -5; if (tpix <= 4000) magStep = -4; if (tpix <= 2000) magStep = -3; if (tpix <= 1000) magStep = -2; if (tpix <= 500) magStep = -1; if (tpix <= 128) magStep = 0; if (tpix <= 64) magStep = 1; if (tpix <= 32) magStep = 2; if (tpix <= 16) magStep = 3; if (tpix <= 8) magStep = 4; if (tpix <= 4) magStep = 5; if (tpix <= 2) magStep = 6; // // if xpos <= 0, then the scene is centered // there is no scroll bar anymore sending // change signals, so we have to do it here: // double xpos = -(mapFromScene(QPointF()).x()); if (xpos <= 0) emit xposChanged(xpos); } else if (event->modifiers() == Qt::ShiftModifier) { QWheelEvent we(event->pos(), event->delta(), event->buttons(), 0, Qt::Horizontal); QGraphicsView::wheelEvent(&we); } else if (event->modifiers() == 0) { QGraphicsView::wheelEvent(event); } else if (event->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier)) { if (step > 0) { for (int i = 0; i < step; ++i) { if (ymag > 3.0) break; scale(1.0, 1.1); ymag *= 1.1; } } else { for (int i = 0; i < -step; ++i) { if (ymag < 0.4) break; scale(1.0, .9); ymag *= .9; } } emit magChanged(xmag, ymag); } }
* Print the DRAM routing info for one base/limit pair. * * Show base, limit, dest node, dest link on that node, read and write * enable, and interleave information. * * @param level Printing level * @param which Register number * @param base Base register * @param lim Limit register */ static void showdram(int level, u8 which, u32 base, u32 lim) { printk(level, "DRAM(%02x)%010llx-%010llx, ->(%d), %s, %s, %s, %d\n", which, (((u64) base & 0xffff0000) << 8), (((u64) lim & 0xffff0000) << 8) + 0xffffff, r_node(lim), re(base), we(base), ileave(base), (lim >> 8) & 3); } /** * Print the config routing info for a config register. * * Show base, limit, dest node, dest link on that node, read and write * enable, and device number compare enable * * @param level Printing level * @param which Register number * @param reg Config register */ static void showconfig(int level, u8 which, u32 reg) { /* Don't use r_node() and r_link() here. */
void BoolView::attach(Propagator *p, int pos, int eflags) { WatchElem we(p->prop_id, pos); if (eflags & EVENT_L) sat.watches[2*v+s].push(we); if (eflags & EVENT_U) sat.watches[2*v+(1-s)].push(we); }
/** * The predicted sharp edge gradient ∇I^s is used as a spatial prior to guide * the recovery of a coarse version of the latent image. * Objective function: E(I) = ||I ⊗ k - B||² + λ||∇I - ∇I^s||² * * @param blurred blurred grayvalue image (B) * @param kernel energy presserving kernel (k) * @param selectionGrads gradients of selected edges (x and y direction) (∇I^s) * @param latent resulting image (I) * @param weight λ, default is 2.0e-3 (weight from paper) */ void coarseImageEstimation(Mat blurred, const Mat& kernel, const array<Mat,2>& selectionGrads, Mat& latent, const float weight = 2.0e-3) { assert(kernel.type() == CV_32F && "works with energy preserving float kernel"); assert(blurred.type() == CV_8U && "works with gray valued blurred image"); // convert grayvalue image to float and normalize it to [0,1] blurred.convertTo(blurred, CV_32F); blurred /= 255.0; // fill kernel with zeros to get to the blurred image size // it's important to use BORDER_ISOLATED flag if the kernel is an ROI of a greater image! Mat pkernel; copyMakeBorder(kernel, pkernel, 0, blurred.rows - kernel.rows, 0, blurred.cols - kernel.cols, BORDER_CONSTANT, Scalar::all(0)); // using sobel filter as gradients dx and dy Mat sobelx = Mat::zeros(blurred.size(), CV_32F); sobelx.at<float>(0,0) = -1; sobelx.at<float>(0,1) = 1; Mat sobely = Mat::zeros(blurred.size(), CV_32F); sobely.at<float>(0,0) = -1; sobely.at<float>(1,0) = 1; // ____ ______ ______ // ( F(k) * F(B) + λ * (F(∂_x) * F(∂_x I^s) + F(∂_y) * F(∂_y I^s)) ) // I = F^-1 * ( --------------------------------------------------------------- ) // ( ____ ______ ______ ) // ( F(k) * F(k) + λ * (F(∂_x) * F(∂_x) + F(∂_y) * F(∂_y)) ) // where * is pointwise multiplication // // here: F(k) = k // F(∂_x I^s) = xS // F(∂_y I^s) = yS // F(∂_x) = dx // F(∂_y) = dy // F(B) = B // compute DFT (withoud padding) // the result are stored as 2 channel matrices: Re(FFT(I)), Im(FFT(I)) Mat K, xS, yS, B, Dx, Dy; deblur::dft(pkernel, K); deblur::dft(selectionGrads[0], xS); deblur::dft(selectionGrads[1], yS); deblur::dft(blurred, B); deblur::dft(sobelx, Dx); deblur::dft(sobely, Dy); // weight from paper complex<float> we(weight, 0.0); // latent image in fourier domain Mat I = Mat::zeros(xS.size(), xS.type()); // pointwise computation of I for (int x = 0; x < xS.cols; x++) { for (int y = 0; y < xS.rows; y++) { // complex entries at the current position complex<float> b(B.at<Vec2f>(y, x)[0], B.at<Vec2f>(y, x)[1]); complex<float> k(K.at<Vec2f>(y, x)[0], K.at<Vec2f>(y, x)[1]); complex<float> xs(xS.at<Vec2f>(y, x)[0], xS.at<Vec2f>(y, x)[1]); complex<float> ys(yS.at<Vec2f>(y, x)[0], yS.at<Vec2f>(y, x)[1]); complex<float> dx(Dx.at<Vec2f>(y, x)[0], Dx.at<Vec2f>(y, x)[1]); complex<float> dy(Dy.at<Vec2f>(y, x)[0], Dy.at<Vec2f>(y, x)[1]); // compute current point of latent image in fourier domain complex<float> i = (conj(k) * b + we * (conj(dx) * xs + conj(dy) * ys)) / (conj(k) * k + we * (conj(dx) * dx + conj(dy) * dy)); I.at<Vec2f>(y, x) = { real(i), imag(i) }; } } // compute inverse DFT of the latent image dft(I, latent, DFT_INVERSE | DFT_REAL_OUTPUT); // threshold the result because it has large negative and positive values // which would result in a very grayish image threshold(latent, latent, 0.0, -1, THRESH_TOZERO); // swap slices of the result // because the image is shifted to the upper-left corner (why??) int x = latent.cols; int y = latent.rows; int hs1 = (kernel.cols - 1) / 2; int hs2 = (kernel.rows - 1) / 2; // create rects per image slice // __________ // | | | // | 0 | 1 | // | | | // |------|---| // | 2 | 3 | // |______|___| // // rect gets the coordinates of the top-left corner, width and height Mat q0(latent, Rect(0, 0, x - hs1, y - hs2)); // Top-Left Mat q1(latent, Rect(x - hs1, 0, hs1, y - hs2)); // Top-Right Mat q2(latent, Rect(0, y - hs2, x - hs1, hs2)); // Bottom-Left Mat q3(latent, Rect(x - hs1, y - hs2, hs1, hs2)); // Bottom-Right Mat latentSwap; cv::hconcat(q3, q2, latentSwap); Mat tmp; cv::hconcat(q1, q0, tmp); cv::vconcat(latentSwap, tmp, latentSwap); // convert result to uchar image convertFloatToUchar(latentSwap, latent); assert(blurred.size() == latent.size() && "Something went wrong - latent and blurred size has to be equal"); }
/** * With the critical edge selection, initial kernel erstimation can be accomplished quickly. * Objective function: E(k) = ||∇I^s ⊗ k - ∇B||² + γ||k||² * * @param selectionGrads array of x and y gradients of final selected edges (∇I^s) [-1, 1] * @param blurredGrads array of x and y gradients of blurred image (∇B) [-1, 1] * @param kernel energy preserving kernel (k) */ void fastKernelEstimation(const array<Mat,2>& selectionGrads, const array<Mat,2>& blurredGrads, Mat& kernel, const float weight = 1e-2) { assert(selectionGrads[0].rows == blurredGrads[0].rows && "matrixes have to be of same size!"); assert(selectionGrads[0].cols == blurredGrads[0].cols && "matrixes have to be of same size!"); // based on Perseval's theorem, perform FFT // __________ __________ // ( F(∂_x I^s) * F(∂_x B) + F(∂_y I^s) * F(∂_y B) ) // k = F^-1 * ( ---------------------------------------------- ) // ( F(∂_x I^s)² + F(∂_y I^s)² + γ ) // where * is pointwise multiplication // __________ // and F(∂_x I^s)² = F(∂_x I^s) * F(∂_x I^s) ! because they mean the norm // // here: F(∂_x I^s) = xS // F(∂_x B) = xB // F(∂_y I^s) = yS // F(∂_y B) = yB // compute FFTs // the result are stored as 2 channel matrices: Re(FFT(I)), Im(FFT(I)) Mat xS, xB, yS, yB; deblur::dft(selectionGrads[0], xS); deblur::dft(blurredGrads[0], xB); deblur::dft(selectionGrads[1], yS); deblur::dft(blurredGrads[1], yB); complex<float> we(weight, 0.0); // kernel in Fourier domain Mat K = Mat::zeros(xS.size(), xS.type()); // pixelwise computation of kernel for (int y = 0; y < K.rows; y++) { for (int x = 0; x < K.cols; x++) { // complex entries at the current position complex<float> xs(xS.at<Vec2f>(y, x)[0], xS.at<Vec2f>(y, x)[1]); complex<float> ys(yS.at<Vec2f>(y, x)[0], yS.at<Vec2f>(y, x)[1]); complex<float> xb(xB.at<Vec2f>(y, x)[0], xB.at<Vec2f>(y, x)[1]); complex<float> yb(yB.at<Vec2f>(y, x)[0], yB.at<Vec2f>(y, x)[1]); // kernel entry in the Fourier space complex<float> k = (conj(xs) * xb + conj(ys) * yb) / (conj(xs) * xs + conj(ys) * ys + we); // (abs(xs) * abs(xs) + abs(ys) * abs(ys) + we); // equivalent K.at<Vec2f>(y, x) = { real(k), imag(k) }; } } // only use the real part of the complex output Mat kernelBig; dft(K, kernelBig, DFT_INVERSE | DFT_REAL_OUTPUT); // FIXME: find kernel inside image (kind of bounding box) instead of force user to // approximate a correct kernel-width (otherwise some information are lost) // cut of kernel in middle of the temporary kernel int x = kernelBig.cols / 2 - kernel.cols / 2; int y = kernelBig.rows / 2 - kernel.rows / 2; swapQuadrants(kernelBig); Mat kernelROI = kernelBig(Rect(x, y, kernel.cols, kernel.rows)); // copy the ROI to the kernel to avoid that some OpenCV functions accidently // uses the information outside of the ROI (like copyMakeBorder()) kernelROI.copyTo(kernel); // threshold kernel to erease negative values threshold(kernel, kernel, 0.0, -1, THRESH_TOZERO); // // kernel has to be energy preserving // // this means: sum(kernel) = 1 kernel /= sum(kernel)[0]; }