• Игра с «материальными» цветами стала ещё проще
    +3
    Еще один полезный сервис — Random Material Generator
  • Мультитест мультиварок: что купить IT-шнику, если хочется плова и борща
    0
    И, кстати, что насчет молочной каши и омлета, этих простых и вкусных блюд? Из-за присутствия в рецепте молока долго хранить их не рекомендуется, поэтому мультиварка небольшого объема подойдет лучше всего. До появления мультиварки и то и другое готовили очень редко. Сейчас часто встречается на столе. Что может быть проще приготовления рисовой или овсяной каши в мультиварке? — В пропорции 4:1 налить молоко и насыпать крупу, бросить кусок сливочного масла, соль, сахар. Закрыть крышку и поставить на режим «Молочная каша». Режим в Панасонике автоматический — выключится сама. Молоко ни разу не убегало. Омлет толщиной 2-3 см ни разу не пригорал.
  • Мультитест мультиварок: что купить IT-шнику, если хочется плова и борща
    0
    Уже, кажется, четвертый год пользуюсь Panasonic SR-TMH10 объемом 2,5 литра. Покупал осознанно именно такого объема на семью из 3-х человек — всегда свежая пища. На мой взгляд, основное преимущество мультиварок — свежая и здоровая пища при минимальном участии человека в процессе готовки. Супы готовлю за 10-15 минут — обжарка овощей (лук, морковка, свекла и т.п.) на режиме «выпечка». Одновременно чищу пару картофелин, достаю из морозилки остальные ингредиенты (разложенное на порционные куски и замороженное мясо, овощные смеси и т.п.). Бросаю все в мультиварку, заливаю водой, соль, перец… Ставлю на режим «тушение» на 3-5 часов и занимаюсь своими делами, так как больше моего участия не требуется. Готовится все одновременно, ничего не разваривается. В итоге всегда свежеприготовленная еда. Готовить каждый день не надоедает, так как на все, повторюсь, тратится 10-15 минут.
  • «Взлом» SmartDeblur 2.2
    +3
    Вот как я это делаю в своем приложении (Java):
    private void putWaterMark(Mat alpha){
    	String logo = _applicationName;
    	String subLogo = "Free version";
    	double fontScale = 1;
    	double maxFontScale = 15;
    	int thickness = 7;
    	int [] baseline = {0};
    	// начало текста по горизонтали
    	double x = Math.random() * alpha.cols()/10+15;
    
    	// начало текста по вертикали
    	double y1 = alpha.rows() / 10.;
    	double y2 = alpha.rows() * 0.9;
    	double y = y1 + Math.random() * (y2 - y1); 
    		
    	Point beginLogo = new Point(x,y);
    		
    	// максимальная ширина текста
    	int maxLength = alpha.cols() - (int) beginLogo.x;
    		
    	// подбор размера фонта под ширину текста:
    	Size textsize = new Size(100,100);
    	for (double d=maxFontScale; d>0; d = d - 0.5){
    		textsize = Core.getTextSize(logo, Core.FONT_HERSHEY_COMPLEX, d, thickness, baseline);
    		if (textsize.width < maxLength) {
    			fontScale = d;
    			break;
    		}
    	}
    		
    	Core.putText(alpha, logo, beginLogo, Core.FONT_HERSHEY_COMPLEX, fontScale, new Scalar(255), thickness);
    	beginLogo.y = beginLogo.y + textsize.height;
    	Core.putText(alpha, subLogo, beginLogo, Core.FONT_HERSHEY_COMPLEX, fontScale/2, new Scalar(255), thickness-3);
    }
    


    Я использую в приложении библиотеку OpenCV, поэтому она же применена здесь при наложении текста.
    На входе пустое изображение (Mat alpha) того же размера как исходное, только в градациях серого (однобайтное). На выходе на него наложен требуемый текст. И сейчас это изображение можно накладывать на исходное. Как — зависит от конкретной реализации, вот у меня здесь есть немного про наложение картинок.
    Вот, кстати результат наложения:
    image
  • Бот для аркады. Часть №2: подключаем OpenCV
  • Как начать учитывать коммунальные услуги с комфортом
    +1
    Так как по долгу службы связан с поверкой приборов учета воды и тепла — пара предложений, связанных с периодической поверкой приборов.
    1. Добавить напоминание при подходе даты следующей поверки прибора учета. Понадобится пара дополнительных полей для каждого прибора — дата последней поверки и межповерочный интервал.
    2. Возможно, пользователям Вашего сервиса удастся немного сэкономить при подаче коллективной заявки на поверку приборов учета воды. Во многих крупных и средних городах России сейчас организована поверка квартирных водосчетчиков без их демонтажа с трубопровода — поверитель выезжает по заявке на указанный адрес. Большинство государственных поверочных центров (ЦСМ) имеют гибкую систему цен на поверку водосчетчиков, не говоря уже о частных поверочных лабораториях. Если с помощью Вашего сервиса удастся скооперироваться жителям одного или нескольких близлежащих домов — они охотно снизят цену поверки до минимальной.
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    0
    И, кстати, спасибо за тест. :)

    Вам спасибо за ценные советы. Дополнил статью новыми тестами.
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    +1
    Попробую дать развернутый ответ.
    Во-первых, вот этот код не работает.
    В приведенном мною выше примере код

    double[] matPix = mat.get(i, j);

    работает для матрицы любого типа. Если же мы создадим массив типа double и попробуем туда скопировать данные матрицы типа CV_8U

    double[] buff = new double[size];
    mat.get(0, 0, buff);

    то произойдет исключение. Залез в исходники OpenCV — все верно, проверяется, правильного ли типа матрица, если нет — возбуждается исключение. Попробовал объявить нужный тип буфера — как сказано здесь. Переписал вышеприведенный код на этот:

    int size = mat.cols();
    for (int i=0; i<mat.rows(); i++){
    	byte[] matPix = new byte[size];
    	byte[] topPix = new byte[size];
    	mat.get(i, 0, matPix);
    	top.get(i, 0, topPix);
    	for (int j=0; j<size; j++) {
    		if (matPix[j]+topPix[j]>255){
    			matPix[j] = (byte) 255;
    		} else {
    			matPix[j] = (byte) ((255 * matPix[j]) / (256 - topPix[j]));
    		}
    	}
    	mat.put(i, 0, matPix);
    }

    Все работает, но вместо эффекта Pencil sketch у меня получается кадр из фильма «Хищник». Почему так? — byte[] в Java — массив со знаком. В OpenCV get и put с массивами типа uchar (пока?) не работают. Но этот оптимизированный код работает быстро. У меня получилось 60, 50 и 50 миллисекунд против 30, 20 и 20 неоптимизированного NDK. Создание еще одного (двух в моем случае) буферных массивов типа char, преобразование данных, работа с ними, затем обратное преобразование возможно даст эффект, но, по-моему, использование NDK для этих целей проще.
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    +1
    Сравнивать скорость у девайсов в данном случае некорректно, так как тестировались копии картинки, уменьшенные пропорционально размеру экранов устройств.
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    +2
    В выходные постараюсь проверить. Самому интересно.
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    0
    Я согласен. В некритичных случаях приведенный Вами пример вполне подходит.
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    0
    Вот, например, существенно более быстрый способ: ровно одно копирование.

    Верно. Только это удвоение (утроение в данном примере) используемой памяти. А если все операции происходят с 13 MP картинкой?
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    0
    Нет. И, как я понимаю, он только с 3-го Андроида работает?
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    0
    Я так понял что аналог нейтивному коду — это закоментированный код?

    Совершенно верно.
    Если же нужно обработать именно Mat, тогда очевидно лучшим решением будет использовать предоставляемые методы, или сконвертировать его в Bitmap и использовать упомянутые методы

    А что Вы подразумеваете под предоставляемыми методами? Методы OpenCV? Так я их и использую в 90% случаев и только там, где нет подходящего метода, пишу свой. Был, кстати, еще случай, когда приложение вылетало при применении стандартной функции OpenCV — поэлементного умножения матриц. Вот тут тоже пришлось переписать ее на C++.
    Что касается преобразований Mat -> Bitmap и обратно, то это очень затратные функции и по времени и по памяти.
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    0
    Там их заменяют
    uchar matPix = mat.at<uchar>(i, j);
    mat.at<uchar>(i, j) = matPix;
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    +1
    Нет.
  • Android SDK vs NDK — сравнение производительности однотипных участков кода
    +1
    Именно сам алгоритм. Вот как то так:
    public static boolean ColorDodgeGray(Mat mat, Mat top){
    		
    		Log.i(TAG,"ColorDodgeGray BEGIN");
    		
    		NativeUtils.nativeColorDodgeGray(mat.getNativeObjAddr(), top.getNativeObjAddr());
    		
    		/*for (int i=0; i<mat.rows(); i++){
    			for (int j=0; j<mat.cols(); j++) {
    				double[] matPix = mat.get(i, j);
    				double[] topPix = top.get(i, j);
    				if (matPix[0]+topPix[0]>255){
    					matPix[0] = 255.;
    				} else {
    					matPix[0] = (255. * matPix[0]) / (256. - topPix[0]);
    				}
    				mat.put(i, j, matPix);
    			}	
    		}*/
    		Log.i(TAG,"ColorDodgeGray END");
    		return true;
    	}