Во-первых, лучше всего указывать свой код в виде текста в уценке кода (старайтесь избегать скриншотов кода).
Что касается вашего вопроса, в этом руководстве по OpenCV это объясняется очень подробно. Примечательно, что сначала вам нужно найти контуры с помощью функции cv2.findContours
, а затем нарисовать их с помощью cv2.drawContours
следующим образом:
import numpy as np
import cv2
im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
где thresh
- это ваше пороговое изображение.
Ваша рукописная, "старая" форма выполняет меньше инструкций и может быть быстрее, хотя необходимо было бы представить ее в соответствии с данным JIT-компилятором для знания наверняка. "Новая" форма определенно не быстрее.
При рассмотрении демонтированного кода (скомпилированный JDK 1.5 Sun), Вы будете видеть, что "новая" форма эквивалентна следующему коду:
1: double[] tmp = doubleArray;
2: for (int i = 0, y = tmp.length; i < y; i++) {
3: double var = tmp[i];
4: someComplexCalculation(var);
5: }
Так, Вы видите, что используется больше локальных переменных. Присвоение doubleArray
кому: tmp
в строке 1 "дополнительно", но она не происходит в цикле и вероятно не может измеряться. Присвоение на var
в строке 3 также дополнительно. Если бы существует разница в производительности, это было бы ответственно.
Строка 1 могла бы казаться ненужной, но это - шаблон для кэширования результата, если массив вычисляется методом прежде, чем ввести цикл.
Тем не менее я использовал бы новую форму, если Вы не должны делать что-то с индексной переменной. Любое различие в производительности, вероятно, будет оптимизировано далеко JIT-компилятором во времени выполнения, и новая форма более ясна. Если Вы продолжаете делать это "вручную", можно пропустить будущую оптимизацию. Обычно хороший компилятор может оптимизировать "глупый" код хорошо, но задержки на "умном" коде.
Мое мнение - то, что Вы не знаете и не должны предполагать. Попытка перехитрить компиляторы в эти дни бесплодна.
Были изученные "Шаблоны" людей времен, которые, казалось, оптимизировали некоторую операцию, но в следующей версии Java те шаблоны были на самом деле медленнее.
Всегда пишите это столь ясный, как Вы возможно можете и не волноваться об оптимизации, пока Вы на самом деле не имеете некоторую пользовательскую спецификацию в руке и не удаетесь отвечать некоторому требованию и даже затем быть очень осторожными для выполнения прежде и за тестами, чтобы гарантировать, что "фиксация" на самом деле улучшила его достаточно для создания той передачи требования.
Компилятор может сделать некоторые удивительные вещи, которые действительно сдули бы Ваши носки, и даже если Вы делаете некоторый тест, который выполняет итерации по некоторому большому спектру, он может работать полностью по-другому, если Вы имеете меньший диапазон или изменяете то, что происходит в цикле.
Как раз вовремя компиляция средств, это может иногда превосходить C по характеристикам, и нет никакой причины, это не может превзойти статический ассемблер по характеристикам в некоторых случаях (блок не может решить заранее, что вызов не требуется, Java может время от времени делать просто это.
Подвести итог его: большая часть значения, которое можно поместить в код, должна записать это, чтобы быть читаемой.
Почему бы не измерить его самостоятельно?
Это звучит немного резким, но этот вид вопросов очень легок проверить себя.
Просто создайте массив и выполните каждый цикл 1000 или больше раз и измерьте количество времени. Повторитесь несколько раз для устранения незначительных сбоев.
Нет никакого различия. Java преобразует расширенное для в нормальное для цикла. Расширенным для является просто "сахар синтаксиса". Сгенерированный байт-код является тем же для обоих циклов.
Я стал очень любопытным на предмет Вашего вопроса, даже после моего предыдущего ответа. Таким образом, я решил проверить его сам также. Я записал эту маленькую часть кода (проигнорируйте математическую правильность о проверке, если число является простым ;-)):
public class TestEnhancedFor {
public static void main(String args[]){
new TestEnhancedFor();
}
public TestEnhancedFor(){
int numberOfItems = 100000;
double[] items = getArrayOfItems(numberOfItems);
int repetitions = 0;
long start, end;
do {
start = System.currentTimeMillis();
doNormalFor(items);
end = System.currentTimeMillis();
System.out.printf("Normal For. Repetition %d: %d\n",
repetitions, end-start);
start = System.currentTimeMillis();
doEnhancedFor(items);
end = System.currentTimeMillis();
System.out.printf("Enhanced For. Repetition %d: %d\n\n",
repetitions, end-start);
} while (++repetitions < 5);
}
private double[] getArrayOfItems(int numberOfItems){
double[] items = new double[numberOfItems];
for (int i=0; i < numberOfItems; i++)
items[i] = i;
return items;
}
private void doSomeComplexCalculation(double item){
// check if item is prime number
for (int i = 3; i < item / 2; i+=2){
if ((item / i) == (int) (item / i)) break;
}
}
private void doNormalFor(double[] items){
for (int i = 0; i < items.length; i++)
doSomeComplexCalculation(items[i]);
}
private void doEnhancedFor(double[] items){
for (double item : items)
doSomeComplexCalculation(item);
}
}
Запущение приложения дало следующие результаты для меня:
Нормальный для. Повторение 0: 5 594 расширенных для. Повторение 0: 5594
Нормальный для. Повторение 1: 5 531 расширенный для. Повторение 1: 5547
Нормальный для. Повторение 2: 5 532 расширенных для. Повторение 2: 5578
Нормальный для. Повторение 3: 5 531 расширенный для. Повторение 3: 5531
Нормальный для. Повторение 4: 5 547 расширенных для. Повторение 4: 5532
Как мы видим, изменение среди результатов является очень маленьким, и иногда нормальный цикл работает быстрее, иногда расширенный цикл быстрее. С тех пор существуют другие приложения, открытые в моем компьютере, я нахожу это нормальным. Кроме того, только первое выполнение медленнее, чем другие - я полагаю, что это имеет отношение к оптимизации JIT.
Средние времена (исключая первое повторение) составляют 5535,25 мс для нормального цикла и 5 547 мс для расширенного цикла. Но мы видим, что лучшее время выполнения для обоих циклов - тот же (5 531 мс), таким образом, я думаю, что мы можем прийти к выводу, что оба цикла имеют ту же производительность - и изменения истекшего времени происходят из-за других приложений (даже ОС) машины.